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"
34 #define ALC880_FRONT_EVENT 0x01
35 #define ALC880_DCVOL_EVENT 0x02
36 #define ALC880_HP_EVENT 0x04
37 #define ALC880_MIC_EVENT 0x08
39 /* ALC880 board config type */
63 #ifdef CONFIG_SND_DEBUG
67 ALC880_MODEL_LAST /* last tag */
80 #ifdef CONFIG_SND_DEBUG
84 ALC260_MODEL_LAST /* last tag */
94 ALC262_HP_BPC_D7000_WL,
95 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 ALC888_FUJITSU_XA3530,
234 ALC883_3ST_6ch_INTEL,
242 /* styles of capture selection */
244 CAPT_MUX = 0, /* only mux based */
245 CAPT_MIX, /* only mixer based */
246 CAPT_1MUX_MIX, /* first mux and other mixers */
250 #define GPIO_MASK 0x03
253 /* codec parameterization */
254 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
255 unsigned int num_mixers;
256 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
258 const struct hda_verb *init_verbs[5]; /* initialization verbs
262 unsigned int num_init_verbs;
264 char *stream_name_analog; /* analog PCM stream */
265 struct hda_pcm_stream *stream_analog_playback;
266 struct hda_pcm_stream *stream_analog_capture;
267 struct hda_pcm_stream *stream_analog_alt_playback;
268 struct hda_pcm_stream *stream_analog_alt_capture;
270 char *stream_name_digital; /* digital PCM stream */
271 struct hda_pcm_stream *stream_digital_playback;
272 struct hda_pcm_stream *stream_digital_capture;
275 struct hda_multi_out multiout; /* playback set-up
276 * max_channels, dacs must be set
277 * dig_out_nid and hp_nid are optional
279 hda_nid_t alt_dac_nid;
283 unsigned int num_adc_nids;
285 hda_nid_t *capsrc_nids;
286 hda_nid_t dig_in_nid; /* digital-in NID; optional */
287 int capture_style; /* capture style (CAPT_*) */
290 unsigned int num_mux_defs;
291 const struct hda_input_mux *input_mux;
292 unsigned int cur_mux[3];
295 const struct hda_channel_mode *channel_mode;
296 int num_channel_mode;
299 /* PCM information */
300 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
302 /* dynamic controls, init_verbs and input_mux */
303 struct auto_pin_cfg autocfg;
304 struct snd_array kctls;
305 struct hda_input_mux private_imux[3];
306 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
309 void (*init_hook)(struct hda_codec *codec);
310 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
312 /* for pin sensing */
313 unsigned int sense_updated: 1;
314 unsigned int jack_present: 1;
315 unsigned int master_sw: 1;
318 unsigned int no_analog :1; /* digital I/O only */
320 /* for virtual master */
321 hda_nid_t vmaster_nid;
322 #ifdef CONFIG_SND_HDA_POWER_SAVE
323 struct hda_loopback_check loopback;
328 unsigned int pll_coef_idx, pll_coef_bit;
330 #ifdef SND_HDA_NEEDS_RESUME
331 #define ALC_MAX_PINS 16
332 unsigned int num_pins;
333 hda_nid_t pin_nids[ALC_MAX_PINS];
334 unsigned int pin_cfgs[ALC_MAX_PINS];
339 * configuration template - to be copied to the spec instance
341 struct alc_config_preset {
342 struct snd_kcontrol_new *mixers[5]; /* should be identical size
345 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
346 const struct hda_verb *init_verbs[5];
347 unsigned int num_dacs;
349 hda_nid_t dig_out_nid; /* optional */
350 hda_nid_t hp_nid; /* optional */
351 unsigned int num_adc_nids;
353 hda_nid_t *capsrc_nids;
354 hda_nid_t dig_in_nid;
355 unsigned int num_channel_mode;
356 const struct hda_channel_mode *channel_mode;
358 unsigned int num_mux_defs;
359 const struct hda_input_mux *input_mux;
360 void (*unsol_event)(struct hda_codec *, unsigned int);
361 void (*init_hook)(struct hda_codec *);
362 #ifdef CONFIG_SND_HDA_POWER_SAVE
363 struct hda_amp_list *loopbacks;
371 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
372 struct snd_ctl_elem_info *uinfo)
374 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
375 struct alc_spec *spec = codec->spec;
376 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
377 if (mux_idx >= spec->num_mux_defs)
379 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
382 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
383 struct snd_ctl_elem_value *ucontrol)
385 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
386 struct alc_spec *spec = codec->spec;
387 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
389 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
393 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
394 struct snd_ctl_elem_value *ucontrol)
396 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
397 struct alc_spec *spec = codec->spec;
398 const struct hda_input_mux *imux;
399 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
400 unsigned int mux_idx;
401 hda_nid_t nid = spec->capsrc_nids ?
402 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
404 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
405 imux = &spec->input_mux[mux_idx];
407 if (spec->capture_style &&
408 !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
409 /* Matrix-mixer style (e.g. ALC882) */
410 unsigned int *cur_val = &spec->cur_mux[adc_idx];
413 idx = ucontrol->value.enumerated.item[0];
414 if (idx >= imux->num_items)
415 idx = imux->num_items - 1;
418 for (i = 0; i < imux->num_items; i++) {
419 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
420 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
421 imux->items[i].index,
427 /* MUX style (e.g. ALC880) */
428 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
429 &spec->cur_mux[adc_idx]);
434 * channel mode setting
436 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
437 struct snd_ctl_elem_info *uinfo)
439 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
440 struct alc_spec *spec = codec->spec;
441 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
442 spec->num_channel_mode);
445 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_value *ucontrol)
448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
449 struct alc_spec *spec = codec->spec;
450 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
451 spec->num_channel_mode,
452 spec->multiout.max_channels);
455 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
456 struct snd_ctl_elem_value *ucontrol)
458 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
459 struct alc_spec *spec = codec->spec;
460 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
461 spec->num_channel_mode,
462 &spec->multiout.max_channels);
463 if (err >= 0 && spec->need_dac_fix)
464 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
469 * Control the mode of pin widget settings via the mixer. "pc" is used
470 * instead of "%" to avoid consequences of accidently treating the % as
471 * being part of a format specifier. Maximum allowed length of a value is
472 * 63 characters plus NULL terminator.
474 * Note: some retasking pin complexes seem to ignore requests for input
475 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
476 * are requested. Therefore order this list so that this behaviour will not
477 * cause problems when mixer clients move through the enum sequentially.
478 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
481 static char *alc_pin_mode_names[] = {
482 "Mic 50pc bias", "Mic 80pc bias",
483 "Line in", "Line out", "Headphone out",
485 static unsigned char alc_pin_mode_values[] = {
486 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
488 /* The control can present all 5 options, or it can limit the options based
489 * in the pin being assumed to be exclusively an input or an output pin. In
490 * addition, "input" pins may or may not process the mic bias option
491 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
492 * accept requests for bias as of chip versions up to March 2006) and/or
493 * wiring in the computer.
495 #define ALC_PIN_DIR_IN 0x00
496 #define ALC_PIN_DIR_OUT 0x01
497 #define ALC_PIN_DIR_INOUT 0x02
498 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
499 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
501 /* Info about the pin modes supported by the different pin direction modes.
502 * For each direction the minimum and maximum values are given.
504 static signed char alc_pin_mode_dir_info[5][2] = {
505 { 0, 2 }, /* ALC_PIN_DIR_IN */
506 { 3, 4 }, /* ALC_PIN_DIR_OUT */
507 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
508 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
509 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
511 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
512 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
513 #define alc_pin_mode_n_items(_dir) \
514 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
516 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
517 struct snd_ctl_elem_info *uinfo)
519 unsigned int item_num = uinfo->value.enumerated.item;
520 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
522 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
524 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
526 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
527 item_num = alc_pin_mode_min(dir);
528 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
532 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
533 struct snd_ctl_elem_value *ucontrol)
536 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
537 hda_nid_t nid = kcontrol->private_value & 0xffff;
538 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
539 long *valp = ucontrol->value.integer.value;
540 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
541 AC_VERB_GET_PIN_WIDGET_CONTROL,
544 /* Find enumerated value for current pinctl setting */
545 i = alc_pin_mode_min(dir);
546 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
548 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
552 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
553 struct snd_ctl_elem_value *ucontrol)
556 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
557 hda_nid_t nid = kcontrol->private_value & 0xffff;
558 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
559 long val = *ucontrol->value.integer.value;
560 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
561 AC_VERB_GET_PIN_WIDGET_CONTROL,
564 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
565 val = alc_pin_mode_min(dir);
567 change = pinctl != alc_pin_mode_values[val];
569 /* Set pin mode to that requested */
570 snd_hda_codec_write_cache(codec, nid, 0,
571 AC_VERB_SET_PIN_WIDGET_CONTROL,
572 alc_pin_mode_values[val]);
574 /* Also enable the retasking pin's input/output as required
575 * for the requested pin mode. Enum values of 2 or less are
578 * Dynamically switching the input/output buffers probably
579 * reduces noise slightly (particularly on input) so we'll
580 * do it. However, having both input and output buffers
581 * enabled simultaneously doesn't seem to be problematic if
582 * this turns out to be necessary in the future.
585 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
586 HDA_AMP_MUTE, HDA_AMP_MUTE);
587 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
590 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
591 HDA_AMP_MUTE, HDA_AMP_MUTE);
592 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
599 #define ALC_PIN_MODE(xname, nid, dir) \
600 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
601 .info = alc_pin_mode_info, \
602 .get = alc_pin_mode_get, \
603 .put = alc_pin_mode_put, \
604 .private_value = nid | (dir<<16) }
606 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
607 * together using a mask with more than one bit set. This control is
608 * currently used only by the ALC260 test model. At this stage they are not
609 * needed for any "production" models.
611 #ifdef CONFIG_SND_DEBUG
612 #define alc_gpio_data_info snd_ctl_boolean_mono_info
614 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
615 struct snd_ctl_elem_value *ucontrol)
617 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
618 hda_nid_t nid = kcontrol->private_value & 0xffff;
619 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
620 long *valp = ucontrol->value.integer.value;
621 unsigned int val = snd_hda_codec_read(codec, nid, 0,
622 AC_VERB_GET_GPIO_DATA, 0x00);
624 *valp = (val & mask) != 0;
627 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
628 struct snd_ctl_elem_value *ucontrol)
631 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
632 hda_nid_t nid = kcontrol->private_value & 0xffff;
633 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
634 long val = *ucontrol->value.integer.value;
635 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
636 AC_VERB_GET_GPIO_DATA,
639 /* Set/unset the masked GPIO bit(s) as needed */
640 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
645 snd_hda_codec_write_cache(codec, nid, 0,
646 AC_VERB_SET_GPIO_DATA, gpio_data);
650 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
651 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
652 .info = alc_gpio_data_info, \
653 .get = alc_gpio_data_get, \
654 .put = alc_gpio_data_put, \
655 .private_value = nid | (mask<<16) }
656 #endif /* CONFIG_SND_DEBUG */
658 /* A switch control to allow the enabling of the digital IO pins on the
659 * ALC260. This is incredibly simplistic; the intention of this control is
660 * to provide something in the test model allowing digital outputs to be
661 * identified if present. If models are found which can utilise these
662 * outputs a more complete mixer control can be devised for those models if
665 #ifdef CONFIG_SND_DEBUG
666 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
668 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
669 struct snd_ctl_elem_value *ucontrol)
671 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
672 hda_nid_t nid = kcontrol->private_value & 0xffff;
673 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
674 long *valp = ucontrol->value.integer.value;
675 unsigned int val = snd_hda_codec_read(codec, nid, 0,
676 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
678 *valp = (val & mask) != 0;
681 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
682 struct snd_ctl_elem_value *ucontrol)
685 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
686 hda_nid_t nid = kcontrol->private_value & 0xffff;
687 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
688 long val = *ucontrol->value.integer.value;
689 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
690 AC_VERB_GET_DIGI_CONVERT_1,
693 /* Set/unset the masked control bit(s) as needed */
694 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
699 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
704 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
705 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
706 .info = alc_spdif_ctrl_info, \
707 .get = alc_spdif_ctrl_get, \
708 .put = alc_spdif_ctrl_put, \
709 .private_value = nid | (mask<<16) }
710 #endif /* CONFIG_SND_DEBUG */
712 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
713 * Again, this is only used in the ALC26x test models to help identify when
714 * the EAPD line must be asserted for features to work.
716 #ifdef CONFIG_SND_DEBUG
717 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
719 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
720 struct snd_ctl_elem_value *ucontrol)
722 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
723 hda_nid_t nid = kcontrol->private_value & 0xffff;
724 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
725 long *valp = ucontrol->value.integer.value;
726 unsigned int val = snd_hda_codec_read(codec, nid, 0,
727 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
729 *valp = (val & mask) != 0;
733 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
734 struct snd_ctl_elem_value *ucontrol)
737 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
738 hda_nid_t nid = kcontrol->private_value & 0xffff;
739 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
740 long val = *ucontrol->value.integer.value;
741 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
742 AC_VERB_GET_EAPD_BTLENABLE,
745 /* Set/unset the masked control bit(s) as needed */
746 change = (!val ? 0 : mask) != (ctrl_data & mask);
751 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
757 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
758 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
759 .info = alc_eapd_ctrl_info, \
760 .get = alc_eapd_ctrl_get, \
761 .put = alc_eapd_ctrl_put, \
762 .private_value = nid | (mask<<16) }
763 #endif /* CONFIG_SND_DEBUG */
767 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
769 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
771 spec->mixers[spec->num_mixers++] = mix;
774 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
776 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
778 spec->init_verbs[spec->num_init_verbs++] = verb;
781 #ifdef CONFIG_PROC_FS
785 static void print_realtek_coef(struct snd_info_buffer *buffer,
786 struct hda_codec *codec, hda_nid_t nid)
792 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
793 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
794 coeff = snd_hda_codec_read(codec, nid, 0,
795 AC_VERB_GET_COEF_INDEX, 0);
796 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
799 #define print_realtek_coef NULL
803 * set up from the preset table
805 static void setup_preset(struct alc_spec *spec,
806 const struct alc_config_preset *preset)
810 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
811 add_mixer(spec, preset->mixers[i]);
812 spec->cap_mixer = preset->cap_mixer;
813 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
815 add_verb(spec, preset->init_verbs[i]);
817 spec->channel_mode = preset->channel_mode;
818 spec->num_channel_mode = preset->num_channel_mode;
819 spec->need_dac_fix = preset->need_dac_fix;
821 spec->multiout.max_channels = spec->channel_mode[0].channels;
823 spec->multiout.num_dacs = preset->num_dacs;
824 spec->multiout.dac_nids = preset->dac_nids;
825 spec->multiout.dig_out_nid = preset->dig_out_nid;
826 spec->multiout.hp_nid = preset->hp_nid;
828 spec->num_mux_defs = preset->num_mux_defs;
829 if (!spec->num_mux_defs)
830 spec->num_mux_defs = 1;
831 spec->input_mux = preset->input_mux;
833 spec->num_adc_nids = preset->num_adc_nids;
834 spec->adc_nids = preset->adc_nids;
835 spec->capsrc_nids = preset->capsrc_nids;
836 spec->dig_in_nid = preset->dig_in_nid;
838 spec->unsol_event = preset->unsol_event;
839 spec->init_hook = preset->init_hook;
840 #ifdef CONFIG_SND_HDA_POWER_SAVE
841 spec->loopback.amplist = preset->loopbacks;
845 /* Enable GPIO mask and set output */
846 static struct hda_verb alc_gpio1_init_verbs[] = {
847 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
848 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
849 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
853 static struct hda_verb alc_gpio2_init_verbs[] = {
854 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
855 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
856 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
860 static struct hda_verb alc_gpio3_init_verbs[] = {
861 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
862 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
863 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
868 * Fix hardware PLL issue
869 * On some codecs, the analog PLL gating control must be off while
870 * the default value is 1.
872 static void alc_fix_pll(struct hda_codec *codec)
874 struct alc_spec *spec = codec->spec;
879 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
881 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
882 AC_VERB_GET_PROC_COEF, 0);
883 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
885 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
886 val & ~(1 << spec->pll_coef_bit));
889 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
890 unsigned int coef_idx, unsigned int coef_bit)
892 struct alc_spec *spec = codec->spec;
894 spec->pll_coef_idx = coef_idx;
895 spec->pll_coef_bit = coef_bit;
899 static void alc_sku_automute(struct hda_codec *codec)
901 struct alc_spec *spec = codec->spec;
902 unsigned int present;
903 unsigned int hp_nid = spec->autocfg.hp_pins[0];
904 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
906 /* need to execute and sync at first */
907 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
908 present = snd_hda_codec_read(codec, hp_nid, 0,
909 AC_VERB_GET_PIN_SENSE, 0);
910 spec->jack_present = (present & 0x80000000) != 0;
911 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
912 spec->jack_present ? 0 : PIN_OUT);
915 #if 0 /* it's broken in some acses -- temporarily disabled */
916 static void alc_mic_automute(struct hda_codec *codec)
918 struct alc_spec *spec = codec->spec;
919 unsigned int present;
920 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
921 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
922 unsigned int mix_nid = spec->capsrc_nids[0];
923 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
925 capsrc_idx_mic = mic_nid - 0x18;
926 capsrc_idx_fmic = fmic_nid - 0x18;
927 present = snd_hda_codec_read(codec, mic_nid, 0,
928 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
929 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
930 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
931 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
932 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
933 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
934 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
937 #define alc_mic_automute(codec) /* NOP */
938 #endif /* disabled */
940 /* unsolicited event for HP jack sensing */
941 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
943 if (codec->vendor_id == 0x10ec0880)
947 if (res == ALC880_HP_EVENT)
948 alc_sku_automute(codec);
950 if (res == ALC880_MIC_EVENT)
951 alc_mic_automute(codec);
954 static void alc_inithook(struct hda_codec *codec)
956 alc_sku_automute(codec);
957 alc_mic_automute(codec);
960 /* additional initialization for ALC888 variants */
961 static void alc888_coef_init(struct hda_codec *codec)
965 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
966 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
967 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
968 if ((tmp & 0xf0) == 2)
970 snd_hda_codec_read(codec, 0x20, 0,
971 AC_VERB_SET_PROC_COEF, 0x830);
974 snd_hda_codec_read(codec, 0x20, 0,
975 AC_VERB_SET_PROC_COEF, 0x3030);
978 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
979 * 31 ~ 16 : Manufacture ID
981 * 7 ~ 0 : Assembly ID
982 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
984 static void alc_subsystem_id(struct hda_codec *codec,
985 unsigned int porta, unsigned int porte,
988 unsigned int ass, tmp, i;
990 struct alc_spec *spec = codec->spec;
992 ass = codec->subsystem_id & 0xffff;
993 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
997 * 31~30 : port conetcivity
1000 * 19~16 : Check sum (15:1)
1005 if (codec->vendor_id == 0x10ec0260)
1007 ass = snd_hda_codec_read(codec, nid, 0,
1008 AC_VERB_GET_CONFIG_DEFAULT, 0);
1009 if (!(ass & 1) && !(ass & 0x100000))
1011 if ((ass >> 30) != 1) /* no physical connection */
1016 for (i = 1; i < 16; i++) {
1020 if (((ass >> 16) & 0xf) != tmp)
1026 * 2 : 0 --> Desktop, 1 --> Laptop
1027 * 3~5 : External Amplifier control
1030 tmp = (ass & 0x38) >> 3; /* external Amp control */
1033 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1036 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1039 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1041 case 5: /* set EAPD output high */
1042 switch (codec->vendor_id) {
1044 snd_hda_codec_write(codec, 0x0f, 0,
1045 AC_VERB_SET_EAPD_BTLENABLE, 2);
1046 snd_hda_codec_write(codec, 0x10, 0,
1047 AC_VERB_SET_EAPD_BTLENABLE, 2);
1058 snd_hda_codec_write(codec, 0x14, 0,
1059 AC_VERB_SET_EAPD_BTLENABLE, 2);
1060 snd_hda_codec_write(codec, 0x15, 0,
1061 AC_VERB_SET_EAPD_BTLENABLE, 2);
1064 switch (codec->vendor_id) {
1066 snd_hda_codec_write(codec, 0x1a, 0,
1067 AC_VERB_SET_COEF_INDEX, 7);
1068 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1069 AC_VERB_GET_PROC_COEF, 0);
1070 snd_hda_codec_write(codec, 0x1a, 0,
1071 AC_VERB_SET_COEF_INDEX, 7);
1072 snd_hda_codec_write(codec, 0x1a, 0,
1073 AC_VERB_SET_PROC_COEF,
1082 snd_hda_codec_write(codec, 0x20, 0,
1083 AC_VERB_SET_COEF_INDEX, 7);
1084 tmp = snd_hda_codec_read(codec, 0x20, 0,
1085 AC_VERB_GET_PROC_COEF, 0);
1086 snd_hda_codec_write(codec, 0x20, 0,
1087 AC_VERB_SET_COEF_INDEX, 7);
1088 snd_hda_codec_write(codec, 0x20, 0,
1089 AC_VERB_SET_PROC_COEF,
1093 /*alc888_coef_init(codec);*/ /* called in alc_init() */
1097 snd_hda_codec_write(codec, 0x20, 0,
1098 AC_VERB_SET_COEF_INDEX, 7);
1099 tmp = snd_hda_codec_read(codec, 0x20, 0,
1100 AC_VERB_GET_PROC_COEF, 0);
1101 snd_hda_codec_write(codec, 0x20, 0,
1102 AC_VERB_SET_COEF_INDEX, 7);
1103 snd_hda_codec_write(codec, 0x20, 0,
1104 AC_VERB_SET_PROC_COEF,
1112 /* is laptop or Desktop and enable the function "Mute internal speaker
1113 * when the external headphone out jack is plugged"
1115 if (!(ass & 0x8000))
1118 * 10~8 : Jack location
1119 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1121 * 15 : 1 --> enable the function "Mute internal speaker
1122 * when the external headphone out jack is plugged"
1124 if (!spec->autocfg.speaker_pins[0]) {
1125 if (spec->autocfg.line_out_pins[0])
1126 spec->autocfg.speaker_pins[0] =
1127 spec->autocfg.line_out_pins[0];
1132 if (!spec->autocfg.hp_pins[0]) {
1133 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1135 spec->autocfg.hp_pins[0] = porta;
1137 spec->autocfg.hp_pins[0] = porte;
1139 spec->autocfg.hp_pins[0] = portd;
1143 if (spec->autocfg.hp_pins[0])
1144 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1145 AC_VERB_SET_UNSOLICITED_ENABLE,
1146 AC_USRSP_EN | ALC880_HP_EVENT);
1148 #if 0 /* it's broken in some acses -- temporarily disabled */
1149 if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1150 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1151 snd_hda_codec_write(codec,
1152 spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1153 AC_VERB_SET_UNSOLICITED_ENABLE,
1154 AC_USRSP_EN | ALC880_MIC_EVENT);
1155 #endif /* disabled */
1157 spec->unsol_event = alc_sku_unsol_event;
1161 * Fix-up pin default configurations
1169 static void alc_fix_pincfg(struct hda_codec *codec,
1170 const struct snd_pci_quirk *quirk,
1171 const struct alc_pincfg **pinfix)
1173 const struct alc_pincfg *cfg;
1175 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1179 cfg = pinfix[quirk->value];
1180 for (; cfg->nid; cfg++) {
1183 for (i = 0; i < 4; i++) {
1184 snd_hda_codec_write(codec, cfg->nid, 0,
1185 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1199 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1200 /* Mic-in jack as mic in */
1201 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1202 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1203 /* Line-in jack as Line in */
1204 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1205 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1206 /* Line-Out as Front */
1207 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1214 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1215 /* Mic-in jack as mic in */
1216 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1217 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1218 /* Line-in jack as Surround */
1219 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1220 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1221 /* Line-Out as Front */
1222 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1229 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1230 /* Mic-in jack as CLFE */
1231 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1232 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1233 /* Line-in jack as Surround */
1234 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1235 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1236 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1237 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1244 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1245 /* Mic-in jack as CLFE */
1246 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1247 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1248 /* Line-in jack as Surround */
1249 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1250 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1251 /* Line-Out as Side */
1252 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1256 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1257 { 2, alc888_4ST_ch2_intel_init },
1258 { 4, alc888_4ST_ch4_intel_init },
1259 { 6, alc888_4ST_ch6_intel_init },
1260 { 8, alc888_4ST_ch8_intel_init },
1264 * ALC888 Fujitsu Siemens Amillo xa3530
1267 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1268 /* Front Mic: set to PIN_IN (empty by default) */
1269 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1270 /* Connect Internal HP to Front */
1271 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1272 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1273 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1274 /* Connect Bass HP to Front */
1275 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1276 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1277 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1278 /* Connect Line-Out side jack (SPDIF) to Side */
1279 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1280 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1281 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1282 /* Connect Mic jack to CLFE */
1283 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1284 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1285 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1286 /* Connect Line-in jack to Surround */
1287 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1288 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1289 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1290 /* Connect HP out jack to Front */
1291 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1292 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1293 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1294 /* Enable unsolicited event for HP jack and Line-out jack */
1295 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1296 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1300 static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec)
1302 unsigned int present;
1304 /* Line out presence */
1305 present = snd_hda_codec_read(codec, 0x17, 0,
1306 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1307 /* HP out presence */
1308 present = present || snd_hda_codec_read(codec, 0x1b, 0,
1309 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1310 bits = present ? HDA_AMP_MUTE : 0;
1311 /* Toggle internal speakers muting */
1312 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1313 HDA_AMP_MUTE, bits);
1314 /* Toggle internal bass muting */
1315 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1316 HDA_AMP_MUTE, bits);
1319 static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec,
1322 if (res >> 26 == ALC880_HP_EVENT)
1323 alc888_fujitsu_xa3530_automute(codec);
1328 * ALC888 Acer Aspire 4930G model
1331 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1332 /* Front Mic: set to PIN_IN (empty by default) */
1333 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1334 /* Unselect Front Mic by default in input mixer 3 */
1335 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1336 /* Enable unsolicited event for HP jack */
1337 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1338 /* Connect Internal HP to front */
1339 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1340 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1341 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1342 /* Connect HP out to front */
1343 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1344 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1345 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1349 static struct hda_input_mux alc888_2_capture_sources[2] = {
1350 /* Front mic only available on one ADC */
1357 { "Front Mic", 0xb },
1370 static struct snd_kcontrol_new alc888_base_mixer[] = {
1371 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1372 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1373 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1374 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1375 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1377 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1378 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1379 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1380 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1381 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1382 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1383 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1384 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1385 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1386 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1387 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1388 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1389 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1390 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1394 static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec)
1396 unsigned int present;
1398 present = snd_hda_codec_read(codec, 0x15, 0,
1399 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1400 bits = present ? HDA_AMP_MUTE : 0;
1401 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1402 HDA_AMP_MUTE, bits);
1405 static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec,
1408 if (res >> 26 == ALC880_HP_EVENT)
1409 alc888_acer_aspire_4930g_automute(codec);
1413 * ALC880 3-stack model
1415 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1416 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1417 * F-Mic = 0x1b, HP = 0x19
1420 static hda_nid_t alc880_dac_nids[4] = {
1421 /* front, rear, clfe, rear_surr */
1422 0x02, 0x05, 0x04, 0x03
1425 static hda_nid_t alc880_adc_nids[3] = {
1430 /* The datasheet says the node 0x07 is connected from inputs,
1431 * but it shows zero connection in the real implementation on some devices.
1432 * Note: this is a 915GAV bug, fixed on 915GLV
1434 static hda_nid_t alc880_adc_nids_alt[2] = {
1439 #define ALC880_DIGOUT_NID 0x06
1440 #define ALC880_DIGIN_NID 0x0a
1442 static struct hda_input_mux alc880_capture_source = {
1446 { "Front Mic", 0x3 },
1452 /* channel source setting (2/6 channel selection for 3-stack) */
1454 static struct hda_verb alc880_threestack_ch2_init[] = {
1455 /* set line-in to input, mute it */
1456 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1457 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1458 /* set mic-in to input vref 80%, mute it */
1459 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1460 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1465 static struct hda_verb alc880_threestack_ch6_init[] = {
1466 /* set line-in to output, unmute it */
1467 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1468 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1469 /* set mic-in to output, unmute it */
1470 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1471 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1475 static struct hda_channel_mode alc880_threestack_modes[2] = {
1476 { 2, alc880_threestack_ch2_init },
1477 { 6, alc880_threestack_ch6_init },
1480 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1481 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1482 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1483 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1484 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1485 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1486 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1487 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1488 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1489 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1490 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1491 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1492 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1493 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1494 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1495 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1496 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1497 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1498 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1499 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1501 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1502 .name = "Channel Mode",
1503 .info = alc_ch_mode_info,
1504 .get = alc_ch_mode_get,
1505 .put = alc_ch_mode_put,
1510 /* capture mixer elements */
1511 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1512 struct snd_ctl_elem_info *uinfo)
1514 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1515 struct alc_spec *spec = codec->spec;
1518 mutex_lock(&codec->control_mutex);
1519 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1521 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1522 mutex_unlock(&codec->control_mutex);
1526 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1527 unsigned int size, unsigned int __user *tlv)
1529 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1530 struct alc_spec *spec = codec->spec;
1533 mutex_lock(&codec->control_mutex);
1534 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1536 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1537 mutex_unlock(&codec->control_mutex);
1541 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1542 struct snd_ctl_elem_value *ucontrol);
1544 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1545 struct snd_ctl_elem_value *ucontrol,
1548 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1549 struct alc_spec *spec = codec->spec;
1550 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1553 mutex_lock(&codec->control_mutex);
1554 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1556 err = func(kcontrol, ucontrol);
1557 mutex_unlock(&codec->control_mutex);
1561 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1562 struct snd_ctl_elem_value *ucontrol)
1564 return alc_cap_getput_caller(kcontrol, ucontrol,
1565 snd_hda_mixer_amp_volume_get);
1568 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1569 struct snd_ctl_elem_value *ucontrol)
1571 return alc_cap_getput_caller(kcontrol, ucontrol,
1572 snd_hda_mixer_amp_volume_put);
1575 /* capture mixer elements */
1576 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1578 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1579 struct snd_ctl_elem_value *ucontrol)
1581 return alc_cap_getput_caller(kcontrol, ucontrol,
1582 snd_hda_mixer_amp_switch_get);
1585 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1586 struct snd_ctl_elem_value *ucontrol)
1588 return alc_cap_getput_caller(kcontrol, ucontrol,
1589 snd_hda_mixer_amp_switch_put);
1592 #define DEFINE_CAPMIX(num) \
1593 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1595 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1596 .name = "Capture Switch", \
1597 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1599 .info = alc_cap_sw_info, \
1600 .get = alc_cap_sw_get, \
1601 .put = alc_cap_sw_put, \
1604 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1605 .name = "Capture Volume", \
1606 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1607 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1608 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1610 .info = alc_cap_vol_info, \
1611 .get = alc_cap_vol_get, \
1612 .put = alc_cap_vol_put, \
1613 .tlv = { .c = alc_cap_vol_tlv }, \
1616 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1617 /* .name = "Capture Source", */ \
1618 .name = "Input Source", \
1620 .info = alc_mux_enum_info, \
1621 .get = alc_mux_enum_get, \
1622 .put = alc_mux_enum_put, \
1627 /* up to three ADCs */
1634 * ALC880 5-stack model
1636 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1638 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1639 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1642 /* additional mixers to alc880_three_stack_mixer */
1643 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1644 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1645 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1649 /* channel source setting (6/8 channel selection for 5-stack) */
1651 static struct hda_verb alc880_fivestack_ch6_init[] = {
1652 /* set line-in to input, mute it */
1653 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1654 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1659 static struct hda_verb alc880_fivestack_ch8_init[] = {
1660 /* set line-in to output, unmute it */
1661 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1662 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1666 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1667 { 6, alc880_fivestack_ch6_init },
1668 { 8, alc880_fivestack_ch8_init },
1673 * ALC880 6-stack model
1675 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1676 * Side = 0x05 (0x0f)
1677 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1678 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1681 static hda_nid_t alc880_6st_dac_nids[4] = {
1682 /* front, rear, clfe, rear_surr */
1683 0x02, 0x03, 0x04, 0x05
1686 static struct hda_input_mux alc880_6stack_capture_source = {
1690 { "Front Mic", 0x1 },
1696 /* fixed 8-channels */
1697 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1701 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1702 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1703 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1704 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1705 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1706 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1707 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1708 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1709 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1710 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1711 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1712 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1713 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1714 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1715 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1716 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1717 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1718 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1719 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1720 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1721 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1723 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1724 .name = "Channel Mode",
1725 .info = alc_ch_mode_info,
1726 .get = alc_ch_mode_get,
1727 .put = alc_ch_mode_put,
1736 * W810 has rear IO for:
1739 * Center/LFE (DAC 04)
1742 * The system also has a pair of internal speakers, and a headphone jack.
1743 * These are both connected to Line2 on the codec, hence to DAC 02.
1745 * There is a variable resistor to control the speaker or headphone
1746 * volume. This is a hardware-only device without a software API.
1748 * Plugging headphones in will disable the internal speakers. This is
1749 * implemented in hardware, not via the driver using jack sense. In
1750 * a similar fashion, plugging into the rear socket marked "front" will
1751 * disable both the speakers and headphones.
1753 * For input, there's a microphone jack, and an "audio in" jack.
1754 * These may not do anything useful with this driver yet, because I
1755 * haven't setup any initialization verbs for these yet...
1758 static hda_nid_t alc880_w810_dac_nids[3] = {
1759 /* front, rear/surround, clfe */
1763 /* fixed 6 channels */
1764 static struct hda_channel_mode alc880_w810_modes[1] = {
1768 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1769 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1770 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1771 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1772 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1773 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1774 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1775 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1776 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1777 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1778 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1786 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1787 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1791 static hda_nid_t alc880_z71v_dac_nids[1] = {
1794 #define ALC880_Z71V_HP_DAC 0x03
1796 /* fixed 2 channels */
1797 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1801 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1802 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1803 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1804 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1805 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1806 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1807 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1808 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1809 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1815 * ALC880 F1734 model
1817 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1818 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1821 static hda_nid_t alc880_f1734_dac_nids[1] = {
1824 #define ALC880_F1734_HP_DAC 0x02
1826 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1827 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1828 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1829 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1830 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1831 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1832 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1838 static struct hda_input_mux alc880_f1734_capture_source = {
1850 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1851 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1852 * Mic = 0x18, Line = 0x1a
1855 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1856 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1858 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1859 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1860 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1861 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1862 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1863 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1864 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1865 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1866 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1867 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1868 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1869 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1870 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1871 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1872 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1874 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1875 .name = "Channel Mode",
1876 .info = alc_ch_mode_info,
1877 .get = alc_ch_mode_get,
1878 .put = alc_ch_mode_put,
1884 * ALC880 ASUS W1V model
1886 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1887 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1888 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1891 /* additional mixers to alc880_asus_mixer */
1892 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1893 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1894 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1898 /* additional mixers to alc880_asus_mixer */
1899 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1900 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1901 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1906 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1907 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1908 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1909 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1910 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1911 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1912 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1913 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1914 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1915 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1920 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1921 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1922 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1923 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1924 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1925 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1926 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1927 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1928 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1929 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1930 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1931 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1932 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1933 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1934 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1935 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1936 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1937 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1938 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1940 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1941 .name = "Channel Mode",
1942 .info = alc_ch_mode_info,
1943 .get = alc_ch_mode_get,
1944 .put = alc_ch_mode_put,
1949 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1950 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1951 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1952 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1953 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1954 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1955 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1956 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1957 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1958 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1959 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1963 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1964 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1965 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1966 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1967 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1968 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1969 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1974 * virtual master controls
1978 * slave controls for virtual master
1980 static const char *alc_slave_vols[] = {
1981 "Front Playback Volume",
1982 "Surround Playback Volume",
1983 "Center Playback Volume",
1984 "LFE Playback Volume",
1985 "Side Playback Volume",
1986 "Headphone Playback Volume",
1987 "Speaker Playback Volume",
1988 "Mono Playback Volume",
1989 "Line-Out Playback Volume",
1990 "PCM Playback Volume",
1994 static const char *alc_slave_sws[] = {
1995 "Front Playback Switch",
1996 "Surround Playback Switch",
1997 "Center Playback Switch",
1998 "LFE Playback Switch",
1999 "Side Playback Switch",
2000 "Headphone Playback Switch",
2001 "Speaker Playback Switch",
2002 "Mono Playback Switch",
2003 "IEC958 Playback Switch",
2008 * build control elements
2011 static void alc_free_kctls(struct hda_codec *codec);
2013 static int alc_build_controls(struct hda_codec *codec)
2015 struct alc_spec *spec = codec->spec;
2019 for (i = 0; i < spec->num_mixers; i++) {
2020 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2024 if (spec->cap_mixer) {
2025 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2029 if (spec->multiout.dig_out_nid) {
2030 err = snd_hda_create_spdif_out_ctls(codec,
2031 spec->multiout.dig_out_nid);
2034 if (!spec->no_analog) {
2035 err = snd_hda_create_spdif_share_sw(codec,
2039 spec->multiout.share_spdif = 1;
2042 if (spec->dig_in_nid) {
2043 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2048 /* if we have no master control, let's create it */
2049 if (!spec->no_analog &&
2050 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2051 unsigned int vmaster_tlv[4];
2052 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2053 HDA_OUTPUT, vmaster_tlv);
2054 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2055 vmaster_tlv, alc_slave_vols);
2059 if (!spec->no_analog &&
2060 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2061 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2062 NULL, alc_slave_sws);
2067 alc_free_kctls(codec); /* no longer needed */
2073 * initialize the codec volumes, etc
2077 * generic initialization of ADC, input mixers and output mixers
2079 static struct hda_verb alc880_volume_init_verbs[] = {
2081 * Unmute ADC0-2 and set the default input to mic-in
2083 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2084 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2085 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2086 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2087 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2088 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2090 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2092 * Note: PASD motherboards uses the Line In 2 as the input for front
2095 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2096 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2105 * Set up output mixers (0x0c - 0x0f)
2107 /* set vol=0 to output mixers */
2108 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2109 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2111 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2112 /* set up input amps for analog loopback */
2113 /* Amp Indices: DAC = 0, mixer = 1 */
2114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2116 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2117 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2118 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2119 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2120 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2121 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2127 * 3-stack pin configuration:
2128 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2130 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2132 * preset connection lists of input pins
2133 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2135 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2136 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2137 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2140 * Set pin mode and muting
2142 /* set front pin widgets 0x14 for output */
2143 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2144 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2145 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2146 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2147 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2148 /* Mic2 (as headphone out) for HP output */
2149 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2150 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2151 /* Line In pin widget for input */
2152 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2153 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2154 /* Line2 (as front mic) pin widget for input and vref at 80% */
2155 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2156 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2157 /* CD pin widget for input */
2158 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2164 * 5-stack pin configuration:
2165 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2166 * line-in/side = 0x1a, f-mic = 0x1b
2168 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2170 * preset connection lists of input pins
2171 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2173 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2174 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2177 * Set pin mode and muting
2179 /* set pin widgets 0x14-0x17 for output */
2180 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2181 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2182 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2183 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2184 /* unmute pins for output (no gain on this amp) */
2185 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2186 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2187 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2188 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2190 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2191 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2192 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2193 /* Mic2 (as headphone out) for HP output */
2194 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2195 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2196 /* Line In pin widget for input */
2197 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2198 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2199 /* Line2 (as front mic) pin widget for input and vref at 80% */
2200 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2201 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2202 /* CD pin widget for input */
2203 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2209 * W810 pin configuration:
2210 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2212 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2213 /* hphone/speaker input selector: front DAC */
2214 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2216 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2217 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2218 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2219 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2220 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2221 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2223 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2224 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2230 * Z71V pin configuration:
2231 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2233 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2236 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2237 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2239 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2240 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2241 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2242 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2248 * 6-stack pin configuration:
2249 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2250 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2252 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2253 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2255 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2256 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2257 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2258 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2259 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2260 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2261 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2262 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2264 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2265 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2266 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2267 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2268 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2269 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2270 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2271 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2272 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2278 * Uniwill pin configuration:
2279 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2282 static struct hda_verb alc880_uniwill_init_verbs[] = {
2283 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2285 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2286 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2287 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2288 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2289 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2290 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2291 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2292 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2293 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2294 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2295 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2296 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2297 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2298 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2300 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2301 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2302 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2303 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2304 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2305 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2306 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2307 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2308 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2310 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2311 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2318 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2320 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2321 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2323 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2324 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2325 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2326 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2327 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2328 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2329 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2330 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2331 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2332 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2333 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2334 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2336 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2337 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2338 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2339 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2340 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2341 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2343 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2344 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2349 static struct hda_verb alc880_beep_init_verbs[] = {
2350 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2354 /* toggle speaker-output according to the hp-jack state */
2355 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
2357 unsigned int present;
2360 present = snd_hda_codec_read(codec, 0x14, 0,
2361 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2362 bits = present ? HDA_AMP_MUTE : 0;
2363 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2364 HDA_AMP_MUTE, bits);
2365 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2366 HDA_AMP_MUTE, bits);
2369 /* auto-toggle front mic */
2370 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2372 unsigned int present;
2375 present = snd_hda_codec_read(codec, 0x18, 0,
2376 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2377 bits = present ? HDA_AMP_MUTE : 0;
2378 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2381 static void alc880_uniwill_automute(struct hda_codec *codec)
2383 alc880_uniwill_hp_automute(codec);
2384 alc880_uniwill_mic_automute(codec);
2387 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2390 /* Looks like the unsol event is incompatible with the standard
2391 * definition. 4bit tag is placed at 28 bit!
2393 switch (res >> 28) {
2394 case ALC880_HP_EVENT:
2395 alc880_uniwill_hp_automute(codec);
2397 case ALC880_MIC_EVENT:
2398 alc880_uniwill_mic_automute(codec);
2403 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2405 unsigned int present;
2408 present = snd_hda_codec_read(codec, 0x14, 0,
2409 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2410 bits = present ? HDA_AMP_MUTE : 0;
2411 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2414 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2416 unsigned int present;
2418 present = snd_hda_codec_read(codec, 0x21, 0,
2419 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2420 present &= HDA_AMP_VOLMASK;
2421 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2422 HDA_AMP_VOLMASK, present);
2423 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2424 HDA_AMP_VOLMASK, present);
2427 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2430 /* Looks like the unsol event is incompatible with the standard
2431 * definition. 4bit tag is placed at 28 bit!
2433 if ((res >> 28) == ALC880_HP_EVENT)
2434 alc880_uniwill_p53_hp_automute(codec);
2435 if ((res >> 28) == ALC880_DCVOL_EVENT)
2436 alc880_uniwill_p53_dcvol_automute(codec);
2440 * F1734 pin configuration:
2441 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2443 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2444 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2445 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2446 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2447 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2448 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2450 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2451 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2452 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2453 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2455 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2456 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2457 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2458 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2459 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2460 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2461 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2462 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2463 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2465 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2466 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2472 * ASUS pin configuration:
2473 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2475 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2476 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2477 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2478 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2479 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2481 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2482 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2483 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2484 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2485 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2486 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2487 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2488 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2490 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2491 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2492 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2493 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2494 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2495 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2496 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2497 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2498 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2503 /* Enable GPIO mask and set output */
2504 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2505 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2507 /* Clevo m520g init */
2508 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2509 /* headphone output */
2510 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2512 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2513 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2515 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2516 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2518 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2519 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2520 /* Mic1 (rear panel) */
2521 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2522 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2523 /* Mic2 (front panel) */
2524 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2525 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2527 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2528 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2529 /* change to EAPD mode */
2530 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2531 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2536 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2537 /* change to EAPD mode */
2538 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2539 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2541 /* Headphone output */
2542 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2544 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2545 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2547 /* Line In pin widget for input */
2548 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2549 /* CD pin widget for input */
2550 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2551 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2552 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2554 /* change to EAPD mode */
2555 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2556 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2562 * LG m1 express dual
2565 * Rear Line-In/Out (blue): 0x14
2566 * Build-in Mic-In: 0x15
2568 * HP-Out (green): 0x1b
2569 * Mic-In/Out (red): 0x19
2573 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2574 static hda_nid_t alc880_lg_dac_nids[3] = {
2578 /* seems analog CD is not working */
2579 static struct hda_input_mux alc880_lg_capture_source = {
2584 { "Internal Mic", 0x6 },
2588 /* 2,4,6 channel modes */
2589 static struct hda_verb alc880_lg_ch2_init[] = {
2590 /* set line-in and mic-in to input */
2591 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2592 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2596 static struct hda_verb alc880_lg_ch4_init[] = {
2597 /* set line-in to out and mic-in to input */
2598 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2599 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2603 static struct hda_verb alc880_lg_ch6_init[] = {
2604 /* set line-in and mic-in to output */
2605 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2606 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2610 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2611 { 2, alc880_lg_ch2_init },
2612 { 4, alc880_lg_ch4_init },
2613 { 6, alc880_lg_ch6_init },
2616 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2617 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2618 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2619 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2620 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2621 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2622 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2623 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2624 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2625 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2626 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2627 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2628 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2629 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2630 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2632 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2633 .name = "Channel Mode",
2634 .info = alc_ch_mode_info,
2635 .get = alc_ch_mode_get,
2636 .put = alc_ch_mode_put,
2641 static struct hda_verb alc880_lg_init_verbs[] = {
2642 /* set capture source to mic-in */
2643 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2644 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2645 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2646 /* mute all amp mixer inputs */
2647 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2648 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2649 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2650 /* line-in to input */
2651 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2652 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2654 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2655 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2657 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2658 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2659 /* mic-in to input */
2660 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2661 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2662 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2664 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2665 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2666 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2668 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2672 /* toggle speaker-output according to the hp-jack state */
2673 static void alc880_lg_automute(struct hda_codec *codec)
2675 unsigned int present;
2678 present = snd_hda_codec_read(codec, 0x1b, 0,
2679 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2680 bits = present ? HDA_AMP_MUTE : 0;
2681 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2682 HDA_AMP_MUTE, bits);
2685 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2687 /* Looks like the unsol event is incompatible with the standard
2688 * definition. 4bit tag is placed at 28 bit!
2690 if ((res >> 28) == 0x01)
2691 alc880_lg_automute(codec);
2700 * Built-in Mic-In: 0x19
2706 static struct hda_input_mux alc880_lg_lw_capture_source = {
2710 { "Internal Mic", 0x1 },
2715 #define alc880_lg_lw_modes alc880_threestack_modes
2717 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2718 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2719 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2720 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2721 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2722 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2723 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2724 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2725 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2726 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2727 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2728 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2729 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2730 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2731 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2733 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2734 .name = "Channel Mode",
2735 .info = alc_ch_mode_info,
2736 .get = alc_ch_mode_get,
2737 .put = alc_ch_mode_put,
2742 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2743 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2744 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2745 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2747 /* set capture source to mic-in */
2748 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2749 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2750 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2751 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2753 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2754 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2756 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2757 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2758 /* mic-in to input */
2759 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2760 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2762 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2763 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2765 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2769 /* toggle speaker-output according to the hp-jack state */
2770 static void alc880_lg_lw_automute(struct hda_codec *codec)
2772 unsigned int present;
2775 present = snd_hda_codec_read(codec, 0x1b, 0,
2776 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2777 bits = present ? HDA_AMP_MUTE : 0;
2778 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2779 HDA_AMP_MUTE, bits);
2782 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2784 /* Looks like the unsol event is incompatible with the standard
2785 * definition. 4bit tag is placed at 28 bit!
2787 if ((res >> 28) == 0x01)
2788 alc880_lg_lw_automute(codec);
2791 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2792 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2793 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2794 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2795 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2796 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2797 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2801 static struct hda_input_mux alc880_medion_rim_capture_source = {
2805 { "Internal Mic", 0x1 },
2809 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2810 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2812 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2813 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2815 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2816 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2817 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2818 /* Mic2 (as headphone out) for HP output */
2819 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2820 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2821 /* Internal Speaker */
2822 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2823 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2825 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2826 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2828 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2832 /* toggle speaker-output according to the hp-jack state */
2833 static void alc880_medion_rim_automute(struct hda_codec *codec)
2835 unsigned int present;
2838 present = snd_hda_codec_read(codec, 0x14, 0,
2839 AC_VERB_GET_PIN_SENSE, 0)
2840 & AC_PINSENSE_PRESENCE;
2841 bits = present ? HDA_AMP_MUTE : 0;
2842 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2843 HDA_AMP_MUTE, bits);
2845 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2847 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2850 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2853 /* Looks like the unsol event is incompatible with the standard
2854 * definition. 4bit tag is placed at 28 bit!
2856 if ((res >> 28) == ALC880_HP_EVENT)
2857 alc880_medion_rim_automute(codec);
2860 #ifdef CONFIG_SND_HDA_POWER_SAVE
2861 static struct hda_amp_list alc880_loopbacks[] = {
2862 { 0x0b, HDA_INPUT, 0 },
2863 { 0x0b, HDA_INPUT, 1 },
2864 { 0x0b, HDA_INPUT, 2 },
2865 { 0x0b, HDA_INPUT, 3 },
2866 { 0x0b, HDA_INPUT, 4 },
2870 static struct hda_amp_list alc880_lg_loopbacks[] = {
2871 { 0x0b, HDA_INPUT, 1 },
2872 { 0x0b, HDA_INPUT, 6 },
2873 { 0x0b, HDA_INPUT, 7 },
2882 static int alc_init(struct hda_codec *codec)
2884 struct alc_spec *spec = codec->spec;
2888 if (codec->vendor_id == 0x10ec0888)
2889 alc888_coef_init(codec);
2891 for (i = 0; i < spec->num_init_verbs; i++)
2892 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2894 if (spec->init_hook)
2895 spec->init_hook(codec);
2900 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2902 struct alc_spec *spec = codec->spec;
2904 if (spec->unsol_event)
2905 spec->unsol_event(codec, res);
2908 #ifdef CONFIG_SND_HDA_POWER_SAVE
2909 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2911 struct alc_spec *spec = codec->spec;
2912 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2917 * Analog playback callbacks
2919 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2920 struct hda_codec *codec,
2921 struct snd_pcm_substream *substream)
2923 struct alc_spec *spec = codec->spec;
2924 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2928 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2929 struct hda_codec *codec,
2930 unsigned int stream_tag,
2931 unsigned int format,
2932 struct snd_pcm_substream *substream)
2934 struct alc_spec *spec = codec->spec;
2935 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2936 stream_tag, format, substream);
2939 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2940 struct hda_codec *codec,
2941 struct snd_pcm_substream *substream)
2943 struct alc_spec *spec = codec->spec;
2944 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2950 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2951 struct hda_codec *codec,
2952 struct snd_pcm_substream *substream)
2954 struct alc_spec *spec = codec->spec;
2955 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2958 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2959 struct hda_codec *codec,
2960 unsigned int stream_tag,
2961 unsigned int format,
2962 struct snd_pcm_substream *substream)
2964 struct alc_spec *spec = codec->spec;
2965 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2966 stream_tag, format, substream);
2969 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2970 struct hda_codec *codec,
2971 struct snd_pcm_substream *substream)
2973 struct alc_spec *spec = codec->spec;
2974 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2980 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2981 struct hda_codec *codec,
2982 unsigned int stream_tag,
2983 unsigned int format,
2984 struct snd_pcm_substream *substream)
2986 struct alc_spec *spec = codec->spec;
2988 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2989 stream_tag, 0, format);
2993 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2994 struct hda_codec *codec,
2995 struct snd_pcm_substream *substream)
2997 struct alc_spec *spec = codec->spec;
2999 snd_hda_codec_cleanup_stream(codec,
3000 spec->adc_nids[substream->number + 1]);
3007 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3011 /* NID is set in alc_build_pcms */
3013 .open = alc880_playback_pcm_open,
3014 .prepare = alc880_playback_pcm_prepare,
3015 .cleanup = alc880_playback_pcm_cleanup
3019 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3023 /* NID is set in alc_build_pcms */
3026 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3030 /* NID is set in alc_build_pcms */
3033 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3034 .substreams = 2, /* can be overridden */
3037 /* NID is set in alc_build_pcms */
3039 .prepare = alc880_alt_capture_pcm_prepare,
3040 .cleanup = alc880_alt_capture_pcm_cleanup
3044 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3048 /* NID is set in alc_build_pcms */
3050 .open = alc880_dig_playback_pcm_open,
3051 .close = alc880_dig_playback_pcm_close,
3052 .prepare = alc880_dig_playback_pcm_prepare
3056 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3060 /* NID is set in alc_build_pcms */
3063 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3064 static struct hda_pcm_stream alc_pcm_null_stream = {
3070 static int alc_build_pcms(struct hda_codec *codec)
3072 struct alc_spec *spec = codec->spec;
3073 struct hda_pcm *info = spec->pcm_rec;
3076 codec->num_pcms = 1;
3077 codec->pcm_info = info;
3079 if (spec->no_analog)
3082 info->name = spec->stream_name_analog;
3083 if (spec->stream_analog_playback) {
3084 if (snd_BUG_ON(!spec->multiout.dac_nids))
3086 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3087 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3089 if (spec->stream_analog_capture) {
3090 if (snd_BUG_ON(!spec->adc_nids))
3092 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3093 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3096 if (spec->channel_mode) {
3097 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3098 for (i = 0; i < spec->num_channel_mode; i++) {
3099 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3100 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3106 /* SPDIF for stream index #1 */
3107 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3108 codec->num_pcms = 2;
3109 info = spec->pcm_rec + 1;
3110 info->name = spec->stream_name_digital;
3111 if (spec->dig_out_type)
3112 info->pcm_type = spec->dig_out_type;
3114 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3115 if (spec->multiout.dig_out_nid &&
3116 spec->stream_digital_playback) {
3117 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3118 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3120 if (spec->dig_in_nid &&
3121 spec->stream_digital_capture) {
3122 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3123 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3125 /* FIXME: do we need this for all Realtek codec models? */
3126 codec->spdif_status_reset = 1;
3129 if (spec->no_analog)
3132 /* If the use of more than one ADC is requested for the current
3133 * model, configure a second analog capture-only PCM.
3135 /* Additional Analaog capture for index #2 */
3136 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3137 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3138 codec->num_pcms = 3;
3139 info = spec->pcm_rec + 2;
3140 info->name = spec->stream_name_analog;
3141 if (spec->alt_dac_nid) {
3142 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3143 *spec->stream_analog_alt_playback;
3144 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3147 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3148 alc_pcm_null_stream;
3149 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3151 if (spec->num_adc_nids > 1) {
3152 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3153 *spec->stream_analog_alt_capture;
3154 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3156 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3157 spec->num_adc_nids - 1;
3159 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3160 alc_pcm_null_stream;
3161 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3168 static void alc_free_kctls(struct hda_codec *codec)
3170 struct alc_spec *spec = codec->spec;
3172 if (spec->kctls.list) {
3173 struct snd_kcontrol_new *kctl = spec->kctls.list;
3175 for (i = 0; i < spec->kctls.used; i++)
3176 kfree(kctl[i].name);
3178 snd_array_free(&spec->kctls);
3181 static void alc_free(struct hda_codec *codec)
3183 struct alc_spec *spec = codec->spec;
3188 alc_free_kctls(codec);
3190 codec->spec = NULL; /* to be sure */
3193 #ifdef SND_HDA_NEEDS_RESUME
3194 static void store_pin_configs(struct hda_codec *codec)
3196 struct alc_spec *spec = codec->spec;
3197 hda_nid_t nid, end_nid;
3199 end_nid = codec->start_nid + codec->num_nodes;
3200 for (nid = codec->start_nid; nid < end_nid; nid++) {
3201 unsigned int wid_caps = get_wcaps(codec, nid);
3202 unsigned int wid_type =
3203 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3204 if (wid_type != AC_WID_PIN)
3206 if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids))
3208 spec->pin_nids[spec->num_pins] = nid;
3209 spec->pin_cfgs[spec->num_pins] =
3210 snd_hda_codec_read(codec, nid, 0,
3211 AC_VERB_GET_CONFIG_DEFAULT, 0);
3216 static void resume_pin_configs(struct hda_codec *codec)
3218 struct alc_spec *spec = codec->spec;
3221 for (i = 0; i < spec->num_pins; i++) {
3222 hda_nid_t pin_nid = spec->pin_nids[i];
3223 unsigned int pin_config = spec->pin_cfgs[i];
3224 snd_hda_codec_write(codec, pin_nid, 0,
3225 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
3226 pin_config & 0x000000ff);
3227 snd_hda_codec_write(codec, pin_nid, 0,
3228 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
3229 (pin_config & 0x0000ff00) >> 8);
3230 snd_hda_codec_write(codec, pin_nid, 0,
3231 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
3232 (pin_config & 0x00ff0000) >> 16);
3233 snd_hda_codec_write(codec, pin_nid, 0,
3234 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
3239 static int alc_resume(struct hda_codec *codec)
3241 resume_pin_configs(codec);
3242 codec->patch_ops.init(codec);
3243 snd_hda_codec_resume_amp(codec);
3244 snd_hda_codec_resume_cache(codec);
3248 #define store_pin_configs(codec)
3253 static struct hda_codec_ops alc_patch_ops = {
3254 .build_controls = alc_build_controls,
3255 .build_pcms = alc_build_pcms,
3258 .unsol_event = alc_unsol_event,
3259 #ifdef SND_HDA_NEEDS_RESUME
3260 .resume = alc_resume,
3262 #ifdef CONFIG_SND_HDA_POWER_SAVE
3263 .check_power_status = alc_check_power_status,
3269 * Test configuration for debugging
3271 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3274 #ifdef CONFIG_SND_DEBUG
3275 static hda_nid_t alc880_test_dac_nids[4] = {
3276 0x02, 0x03, 0x04, 0x05
3279 static struct hda_input_mux alc880_test_capture_source = {
3288 { "Surround", 0x6 },
3292 static struct hda_channel_mode alc880_test_modes[4] = {
3299 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3300 struct snd_ctl_elem_info *uinfo)
3302 static char *texts[] = {
3303 "N/A", "Line Out", "HP Out",
3304 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3306 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3308 uinfo->value.enumerated.items = 8;
3309 if (uinfo->value.enumerated.item >= 8)
3310 uinfo->value.enumerated.item = 7;
3311 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3315 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3316 struct snd_ctl_elem_value *ucontrol)
3318 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3319 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3320 unsigned int pin_ctl, item = 0;
3322 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3323 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3324 if (pin_ctl & AC_PINCTL_OUT_EN) {
3325 if (pin_ctl & AC_PINCTL_HP_EN)
3329 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3330 switch (pin_ctl & AC_PINCTL_VREFEN) {
3331 case AC_PINCTL_VREF_HIZ: item = 3; break;
3332 case AC_PINCTL_VREF_50: item = 4; break;
3333 case AC_PINCTL_VREF_GRD: item = 5; break;
3334 case AC_PINCTL_VREF_80: item = 6; break;
3335 case AC_PINCTL_VREF_100: item = 7; break;
3338 ucontrol->value.enumerated.item[0] = item;
3342 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3343 struct snd_ctl_elem_value *ucontrol)
3345 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3346 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3347 static unsigned int ctls[] = {
3348 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3349 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3350 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3351 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3352 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3353 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3355 unsigned int old_ctl, new_ctl;
3357 old_ctl = snd_hda_codec_read(codec, nid, 0,
3358 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3359 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3360 if (old_ctl != new_ctl) {
3362 snd_hda_codec_write_cache(codec, nid, 0,
3363 AC_VERB_SET_PIN_WIDGET_CONTROL,
3365 val = ucontrol->value.enumerated.item[0] >= 3 ?
3367 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3374 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3375 struct snd_ctl_elem_info *uinfo)
3377 static char *texts[] = {
3378 "Front", "Surround", "CLFE", "Side"
3380 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3382 uinfo->value.enumerated.items = 4;
3383 if (uinfo->value.enumerated.item >= 4)
3384 uinfo->value.enumerated.item = 3;
3385 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3389 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3390 struct snd_ctl_elem_value *ucontrol)
3392 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3393 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3396 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3397 ucontrol->value.enumerated.item[0] = sel & 3;
3401 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3402 struct snd_ctl_elem_value *ucontrol)
3404 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3405 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3408 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3409 if (ucontrol->value.enumerated.item[0] != sel) {
3410 sel = ucontrol->value.enumerated.item[0] & 3;
3411 snd_hda_codec_write_cache(codec, nid, 0,
3412 AC_VERB_SET_CONNECT_SEL, sel);
3418 #define PIN_CTL_TEST(xname,nid) { \
3419 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3421 .info = alc_test_pin_ctl_info, \
3422 .get = alc_test_pin_ctl_get, \
3423 .put = alc_test_pin_ctl_put, \
3424 .private_value = nid \
3427 #define PIN_SRC_TEST(xname,nid) { \
3428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3430 .info = alc_test_pin_src_info, \
3431 .get = alc_test_pin_src_get, \
3432 .put = alc_test_pin_src_put, \
3433 .private_value = nid \
3436 static struct snd_kcontrol_new alc880_test_mixer[] = {
3437 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3438 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3439 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3440 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3441 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3442 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3443 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3444 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3445 PIN_CTL_TEST("Front Pin Mode", 0x14),
3446 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3447 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3448 PIN_CTL_TEST("Side Pin Mode", 0x17),
3449 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3450 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3451 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3452 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3453 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3454 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3455 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3456 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3457 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3458 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3459 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3460 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3461 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3462 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3463 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3464 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3465 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3466 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3468 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3469 .name = "Channel Mode",
3470 .info = alc_ch_mode_info,
3471 .get = alc_ch_mode_get,
3472 .put = alc_ch_mode_put,
3477 static struct hda_verb alc880_test_init_verbs[] = {
3478 /* Unmute inputs of 0x0c - 0x0f */
3479 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3480 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3481 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3482 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3483 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3484 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3485 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3486 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3487 /* Vol output for 0x0c-0x0f */
3488 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3489 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3490 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3491 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3492 /* Set output pins 0x14-0x17 */
3493 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3495 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3496 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3497 /* Unmute output pins 0x14-0x17 */
3498 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3499 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3500 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3501 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3502 /* Set input pins 0x18-0x1c */
3503 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3504 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3505 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3506 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3507 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3508 /* Mute input pins 0x18-0x1b */
3509 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3510 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3511 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3512 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3514 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3515 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3516 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3517 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3518 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3519 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3520 /* Analog input/passthru */
3521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3522 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3523 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3524 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3525 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3533 static const char *alc880_models[ALC880_MODEL_LAST] = {
3534 [ALC880_3ST] = "3stack",
3535 [ALC880_TCL_S700] = "tcl",
3536 [ALC880_3ST_DIG] = "3stack-digout",
3537 [ALC880_CLEVO] = "clevo",
3538 [ALC880_5ST] = "5stack",
3539 [ALC880_5ST_DIG] = "5stack-digout",
3540 [ALC880_W810] = "w810",
3541 [ALC880_Z71V] = "z71v",
3542 [ALC880_6ST] = "6stack",
3543 [ALC880_6ST_DIG] = "6stack-digout",
3544 [ALC880_ASUS] = "asus",
3545 [ALC880_ASUS_W1V] = "asus-w1v",
3546 [ALC880_ASUS_DIG] = "asus-dig",
3547 [ALC880_ASUS_DIG2] = "asus-dig2",
3548 [ALC880_UNIWILL_DIG] = "uniwill",
3549 [ALC880_UNIWILL_P53] = "uniwill-p53",
3550 [ALC880_FUJITSU] = "fujitsu",
3551 [ALC880_F1734] = "F1734",
3553 [ALC880_LG_LW] = "lg-lw",
3554 [ALC880_MEDION_RIM] = "medion",
3555 #ifdef CONFIG_SND_DEBUG
3556 [ALC880_TEST] = "test",
3558 [ALC880_AUTO] = "auto",
3561 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3562 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3563 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3564 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3565 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3566 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3567 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3568 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3569 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3570 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3571 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3572 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3573 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3574 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3575 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3576 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3577 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3578 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3579 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3580 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3581 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3582 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3583 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3584 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3585 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3586 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3587 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3588 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3589 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3590 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3591 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3592 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3593 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3594 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3595 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3596 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3597 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3598 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3599 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3600 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3601 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3602 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3603 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3604 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3605 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3606 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3607 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3608 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3609 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3610 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3611 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3612 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3613 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3614 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3615 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3616 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3617 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3618 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3619 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3620 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3621 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3622 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3623 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3624 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3625 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3626 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3627 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3628 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3629 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3630 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3631 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3632 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3637 * ALC880 codec presets
3639 static struct alc_config_preset alc880_presets[] = {
3641 .mixers = { alc880_three_stack_mixer },
3642 .init_verbs = { alc880_volume_init_verbs,
3643 alc880_pin_3stack_init_verbs },
3644 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3645 .dac_nids = alc880_dac_nids,
3646 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3647 .channel_mode = alc880_threestack_modes,
3649 .input_mux = &alc880_capture_source,
3651 [ALC880_3ST_DIG] = {
3652 .mixers = { alc880_three_stack_mixer },
3653 .init_verbs = { alc880_volume_init_verbs,
3654 alc880_pin_3stack_init_verbs },
3655 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3656 .dac_nids = alc880_dac_nids,
3657 .dig_out_nid = ALC880_DIGOUT_NID,
3658 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3659 .channel_mode = alc880_threestack_modes,
3661 .input_mux = &alc880_capture_source,
3663 [ALC880_TCL_S700] = {
3664 .mixers = { alc880_tcl_s700_mixer },
3665 .init_verbs = { alc880_volume_init_verbs,
3666 alc880_pin_tcl_S700_init_verbs,
3667 alc880_gpio2_init_verbs },
3668 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3669 .dac_nids = alc880_dac_nids,
3670 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3671 .num_adc_nids = 1, /* single ADC */
3673 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3674 .channel_mode = alc880_2_jack_modes,
3675 .input_mux = &alc880_capture_source,
3678 .mixers = { alc880_three_stack_mixer,
3679 alc880_five_stack_mixer},
3680 .init_verbs = { alc880_volume_init_verbs,
3681 alc880_pin_5stack_init_verbs },
3682 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3683 .dac_nids = alc880_dac_nids,
3684 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3685 .channel_mode = alc880_fivestack_modes,
3686 .input_mux = &alc880_capture_source,
3688 [ALC880_5ST_DIG] = {
3689 .mixers = { alc880_three_stack_mixer,
3690 alc880_five_stack_mixer },
3691 .init_verbs = { alc880_volume_init_verbs,
3692 alc880_pin_5stack_init_verbs },
3693 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3694 .dac_nids = alc880_dac_nids,
3695 .dig_out_nid = ALC880_DIGOUT_NID,
3696 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3697 .channel_mode = alc880_fivestack_modes,
3698 .input_mux = &alc880_capture_source,
3701 .mixers = { alc880_six_stack_mixer },
3702 .init_verbs = { alc880_volume_init_verbs,
3703 alc880_pin_6stack_init_verbs },
3704 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3705 .dac_nids = alc880_6st_dac_nids,
3706 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3707 .channel_mode = alc880_sixstack_modes,
3708 .input_mux = &alc880_6stack_capture_source,
3710 [ALC880_6ST_DIG] = {
3711 .mixers = { alc880_six_stack_mixer },
3712 .init_verbs = { alc880_volume_init_verbs,
3713 alc880_pin_6stack_init_verbs },
3714 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3715 .dac_nids = alc880_6st_dac_nids,
3716 .dig_out_nid = ALC880_DIGOUT_NID,
3717 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3718 .channel_mode = alc880_sixstack_modes,
3719 .input_mux = &alc880_6stack_capture_source,
3722 .mixers = { alc880_w810_base_mixer },
3723 .init_verbs = { alc880_volume_init_verbs,
3724 alc880_pin_w810_init_verbs,
3725 alc880_gpio2_init_verbs },
3726 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3727 .dac_nids = alc880_w810_dac_nids,
3728 .dig_out_nid = ALC880_DIGOUT_NID,
3729 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3730 .channel_mode = alc880_w810_modes,
3731 .input_mux = &alc880_capture_source,
3734 .mixers = { alc880_z71v_mixer },
3735 .init_verbs = { alc880_volume_init_verbs,
3736 alc880_pin_z71v_init_verbs },
3737 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3738 .dac_nids = alc880_z71v_dac_nids,
3739 .dig_out_nid = ALC880_DIGOUT_NID,
3741 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3742 .channel_mode = alc880_2_jack_modes,
3743 .input_mux = &alc880_capture_source,
3746 .mixers = { alc880_f1734_mixer },
3747 .init_verbs = { alc880_volume_init_verbs,
3748 alc880_pin_f1734_init_verbs },
3749 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3750 .dac_nids = alc880_f1734_dac_nids,
3752 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3753 .channel_mode = alc880_2_jack_modes,
3754 .input_mux = &alc880_f1734_capture_source,
3755 .unsol_event = alc880_uniwill_p53_unsol_event,
3756 .init_hook = alc880_uniwill_p53_hp_automute,
3759 .mixers = { alc880_asus_mixer },
3760 .init_verbs = { alc880_volume_init_verbs,
3761 alc880_pin_asus_init_verbs,
3762 alc880_gpio1_init_verbs },
3763 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3764 .dac_nids = alc880_asus_dac_nids,
3765 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3766 .channel_mode = alc880_asus_modes,
3768 .input_mux = &alc880_capture_source,
3770 [ALC880_ASUS_DIG] = {
3771 .mixers = { alc880_asus_mixer },
3772 .init_verbs = { alc880_volume_init_verbs,
3773 alc880_pin_asus_init_verbs,
3774 alc880_gpio1_init_verbs },
3775 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3776 .dac_nids = alc880_asus_dac_nids,
3777 .dig_out_nid = ALC880_DIGOUT_NID,
3778 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3779 .channel_mode = alc880_asus_modes,
3781 .input_mux = &alc880_capture_source,
3783 [ALC880_ASUS_DIG2] = {
3784 .mixers = { alc880_asus_mixer },
3785 .init_verbs = { alc880_volume_init_verbs,
3786 alc880_pin_asus_init_verbs,
3787 alc880_gpio2_init_verbs }, /* use GPIO2 */
3788 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3789 .dac_nids = alc880_asus_dac_nids,
3790 .dig_out_nid = ALC880_DIGOUT_NID,
3791 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3792 .channel_mode = alc880_asus_modes,
3794 .input_mux = &alc880_capture_source,
3796 [ALC880_ASUS_W1V] = {
3797 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3798 .init_verbs = { alc880_volume_init_verbs,
3799 alc880_pin_asus_init_verbs,
3800 alc880_gpio1_init_verbs },
3801 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3802 .dac_nids = alc880_asus_dac_nids,
3803 .dig_out_nid = ALC880_DIGOUT_NID,
3804 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3805 .channel_mode = alc880_asus_modes,
3807 .input_mux = &alc880_capture_source,
3809 [ALC880_UNIWILL_DIG] = {
3810 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3811 .init_verbs = { alc880_volume_init_verbs,
3812 alc880_pin_asus_init_verbs },
3813 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3814 .dac_nids = alc880_asus_dac_nids,
3815 .dig_out_nid = ALC880_DIGOUT_NID,
3816 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3817 .channel_mode = alc880_asus_modes,
3819 .input_mux = &alc880_capture_source,
3821 [ALC880_UNIWILL] = {
3822 .mixers = { alc880_uniwill_mixer },
3823 .init_verbs = { alc880_volume_init_verbs,
3824 alc880_uniwill_init_verbs },
3825 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3826 .dac_nids = alc880_asus_dac_nids,
3827 .dig_out_nid = ALC880_DIGOUT_NID,
3828 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3829 .channel_mode = alc880_threestack_modes,
3831 .input_mux = &alc880_capture_source,
3832 .unsol_event = alc880_uniwill_unsol_event,
3833 .init_hook = alc880_uniwill_automute,
3835 [ALC880_UNIWILL_P53] = {
3836 .mixers = { alc880_uniwill_p53_mixer },
3837 .init_verbs = { alc880_volume_init_verbs,
3838 alc880_uniwill_p53_init_verbs },
3839 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3840 .dac_nids = alc880_asus_dac_nids,
3841 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3842 .channel_mode = alc880_threestack_modes,
3843 .input_mux = &alc880_capture_source,
3844 .unsol_event = alc880_uniwill_p53_unsol_event,
3845 .init_hook = alc880_uniwill_p53_hp_automute,
3847 [ALC880_FUJITSU] = {
3848 .mixers = { alc880_fujitsu_mixer,
3849 alc880_pcbeep_mixer, },
3850 .init_verbs = { alc880_volume_init_verbs,
3851 alc880_uniwill_p53_init_verbs,
3852 alc880_beep_init_verbs },
3853 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3854 .dac_nids = alc880_dac_nids,
3855 .dig_out_nid = ALC880_DIGOUT_NID,
3856 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3857 .channel_mode = alc880_2_jack_modes,
3858 .input_mux = &alc880_capture_source,
3859 .unsol_event = alc880_uniwill_p53_unsol_event,
3860 .init_hook = alc880_uniwill_p53_hp_automute,
3863 .mixers = { alc880_three_stack_mixer },
3864 .init_verbs = { alc880_volume_init_verbs,
3865 alc880_pin_clevo_init_verbs },
3866 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3867 .dac_nids = alc880_dac_nids,
3869 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3870 .channel_mode = alc880_threestack_modes,
3872 .input_mux = &alc880_capture_source,
3875 .mixers = { alc880_lg_mixer },
3876 .init_verbs = { alc880_volume_init_verbs,
3877 alc880_lg_init_verbs },
3878 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3879 .dac_nids = alc880_lg_dac_nids,
3880 .dig_out_nid = ALC880_DIGOUT_NID,
3881 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3882 .channel_mode = alc880_lg_ch_modes,
3884 .input_mux = &alc880_lg_capture_source,
3885 .unsol_event = alc880_lg_unsol_event,
3886 .init_hook = alc880_lg_automute,
3887 #ifdef CONFIG_SND_HDA_POWER_SAVE
3888 .loopbacks = alc880_lg_loopbacks,
3892 .mixers = { alc880_lg_lw_mixer },
3893 .init_verbs = { alc880_volume_init_verbs,
3894 alc880_lg_lw_init_verbs },
3895 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3896 .dac_nids = alc880_dac_nids,
3897 .dig_out_nid = ALC880_DIGOUT_NID,
3898 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3899 .channel_mode = alc880_lg_lw_modes,
3900 .input_mux = &alc880_lg_lw_capture_source,
3901 .unsol_event = alc880_lg_lw_unsol_event,
3902 .init_hook = alc880_lg_lw_automute,
3904 [ALC880_MEDION_RIM] = {
3905 .mixers = { alc880_medion_rim_mixer },
3906 .init_verbs = { alc880_volume_init_verbs,
3907 alc880_medion_rim_init_verbs,
3908 alc_gpio2_init_verbs },
3909 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3910 .dac_nids = alc880_dac_nids,
3911 .dig_out_nid = ALC880_DIGOUT_NID,
3912 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3913 .channel_mode = alc880_2_jack_modes,
3914 .input_mux = &alc880_medion_rim_capture_source,
3915 .unsol_event = alc880_medion_rim_unsol_event,
3916 .init_hook = alc880_medion_rim_automute,
3918 #ifdef CONFIG_SND_DEBUG
3920 .mixers = { alc880_test_mixer },
3921 .init_verbs = { alc880_test_init_verbs },
3922 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3923 .dac_nids = alc880_test_dac_nids,
3924 .dig_out_nid = ALC880_DIGOUT_NID,
3925 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3926 .channel_mode = alc880_test_modes,
3927 .input_mux = &alc880_test_capture_source,
3933 * Automatic parse of I/O pins from the BIOS configuration
3938 ALC_CTL_WIDGET_MUTE,
3941 static struct snd_kcontrol_new alc880_control_templates[] = {
3942 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3943 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3944 HDA_BIND_MUTE(NULL, 0, 0, 0),
3947 /* add dynamic controls */
3948 static int add_control(struct alc_spec *spec, int type, const char *name,
3951 struct snd_kcontrol_new *knew;
3953 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3954 knew = snd_array_new(&spec->kctls);
3957 *knew = alc880_control_templates[type];
3958 knew->name = kstrdup(name, GFP_KERNEL);
3961 knew->private_value = val;
3965 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3966 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3967 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3968 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3969 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3970 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3971 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3972 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3973 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3974 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3975 #define ALC880_PIN_CD_NID 0x1c
3977 /* fill in the dac_nids table from the parsed pin configuration */
3978 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3979 const struct auto_pin_cfg *cfg)
3985 memset(assigned, 0, sizeof(assigned));
3986 spec->multiout.dac_nids = spec->private_dac_nids;
3988 /* check the pins hardwired to audio widget */
3989 for (i = 0; i < cfg->line_outs; i++) {
3990 nid = cfg->line_out_pins[i];
3991 if (alc880_is_fixed_pin(nid)) {
3992 int idx = alc880_fixed_pin_idx(nid);
3993 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3997 /* left pins can be connect to any audio widget */
3998 for (i = 0; i < cfg->line_outs; i++) {
3999 nid = cfg->line_out_pins[i];
4000 if (alc880_is_fixed_pin(nid))
4002 /* search for an empty channel */
4003 for (j = 0; j < cfg->line_outs; j++) {
4005 spec->multiout.dac_nids[i] =
4006 alc880_idx_to_dac(j);
4012 spec->multiout.num_dacs = cfg->line_outs;
4016 /* add playback controls from the parsed DAC table */
4017 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4018 const struct auto_pin_cfg *cfg)
4021 static const char *chname[4] = {
4022 "Front", "Surround", NULL /*CLFE*/, "Side"
4027 for (i = 0; i < cfg->line_outs; i++) {
4028 if (!spec->multiout.dac_nids[i])
4030 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4033 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4034 "Center Playback Volume",
4035 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4039 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4040 "LFE Playback Volume",
4041 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4045 err = add_control(spec, ALC_CTL_BIND_MUTE,
4046 "Center Playback Switch",
4047 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4051 err = add_control(spec, ALC_CTL_BIND_MUTE,
4052 "LFE Playback Switch",
4053 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4058 sprintf(name, "%s Playback Volume", chname[i]);
4059 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4060 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4064 sprintf(name, "%s Playback Switch", chname[i]);
4065 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4066 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4075 /* add playback controls for speaker and HP outputs */
4076 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4086 if (alc880_is_fixed_pin(pin)) {
4087 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4088 /* specify the DAC as the extra output */
4089 if (!spec->multiout.hp_nid)
4090 spec->multiout.hp_nid = nid;
4092 spec->multiout.extra_out_nid[0] = nid;
4093 /* control HP volume/switch on the output mixer amp */
4094 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4095 sprintf(name, "%s Playback Volume", pfx);
4096 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4097 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4100 sprintf(name, "%s Playback Switch", pfx);
4101 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4102 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4105 } else if (alc880_is_multi_pin(pin)) {
4106 /* set manual connection */
4107 /* we have only a switch on HP-out PIN */
4108 sprintf(name, "%s Playback Switch", pfx);
4109 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4110 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4117 /* create input playback/capture controls for the given pin */
4118 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4119 const char *ctlname,
4120 int idx, hda_nid_t mix_nid)
4125 sprintf(name, "%s Playback Volume", ctlname);
4126 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4127 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4130 sprintf(name, "%s Playback Switch", ctlname);
4131 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4132 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4138 /* create playback/capture controls for input pins */
4139 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4140 const struct auto_pin_cfg *cfg)
4142 struct hda_input_mux *imux = &spec->private_imux[0];
4145 for (i = 0; i < AUTO_PIN_LAST; i++) {
4146 if (alc880_is_input_pin(cfg->input_pins[i])) {
4147 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4148 err = new_analog_input(spec, cfg->input_pins[i],
4149 auto_pin_cfg_labels[i],
4153 imux->items[imux->num_items].label =
4154 auto_pin_cfg_labels[i];
4155 imux->items[imux->num_items].index =
4156 alc880_input_pin_idx(cfg->input_pins[i]);
4163 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4164 unsigned int pin_type)
4166 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4169 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4173 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4174 hda_nid_t nid, int pin_type,
4177 alc_set_pin_output(codec, nid, pin_type);
4178 /* need the manual connection? */
4179 if (alc880_is_multi_pin(nid)) {
4180 struct alc_spec *spec = codec->spec;
4181 int idx = alc880_multi_pin_idx(nid);
4182 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4183 AC_VERB_SET_CONNECT_SEL,
4184 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4188 static int get_pin_type(int line_out_type)
4190 if (line_out_type == AUTO_PIN_HP_OUT)
4196 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4198 struct alc_spec *spec = codec->spec;
4201 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
4202 for (i = 0; i < spec->autocfg.line_outs; i++) {
4203 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4204 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4205 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4209 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4211 struct alc_spec *spec = codec->spec;
4214 pin = spec->autocfg.speaker_pins[0];
4215 if (pin) /* connect to front */
4216 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4217 pin = spec->autocfg.hp_pins[0];
4218 if (pin) /* connect to front */
4219 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4222 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4224 struct alc_spec *spec = codec->spec;
4227 for (i = 0; i < AUTO_PIN_LAST; i++) {
4228 hda_nid_t nid = spec->autocfg.input_pins[i];
4229 if (alc880_is_input_pin(nid)) {
4230 snd_hda_codec_write(codec, nid, 0,
4231 AC_VERB_SET_PIN_WIDGET_CONTROL,
4232 i <= AUTO_PIN_FRONT_MIC ?
4233 PIN_VREF80 : PIN_IN);
4234 if (nid != ALC880_PIN_CD_NID)
4235 snd_hda_codec_write(codec, nid, 0,
4236 AC_VERB_SET_AMP_GAIN_MUTE,
4242 /* parse the BIOS configuration and set up the alc_spec */
4243 /* return 1 if successful, 0 if the proper config is not found,
4244 * or a negative error code
4246 static int alc880_parse_auto_config(struct hda_codec *codec)
4248 struct alc_spec *spec = codec->spec;
4250 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4252 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4256 if (!spec->autocfg.line_outs)
4257 return 0; /* can't find valid BIOS pin config */
4259 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4262 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4265 err = alc880_auto_create_extra_out(spec,
4266 spec->autocfg.speaker_pins[0],
4270 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4274 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4278 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4280 if (spec->autocfg.dig_out_pin)
4281 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
4282 if (spec->autocfg.dig_in_pin)
4283 spec->dig_in_nid = ALC880_DIGIN_NID;
4285 if (spec->kctls.list)
4286 add_mixer(spec, spec->kctls.list);
4288 add_verb(spec, alc880_volume_init_verbs);
4290 spec->num_mux_defs = 1;
4291 spec->input_mux = &spec->private_imux[0];
4293 store_pin_configs(codec);
4297 /* additional initialization for auto-configuration model */
4298 static void alc880_auto_init(struct hda_codec *codec)
4300 struct alc_spec *spec = codec->spec;
4301 alc880_auto_init_multi_out(codec);
4302 alc880_auto_init_extra_out(codec);
4303 alc880_auto_init_analog_input(codec);
4304 if (spec->unsol_event)
4305 alc_inithook(codec);
4309 * OK, here we have finally the patch for ALC880
4312 static void set_capture_mixer(struct alc_spec *spec)
4314 static struct snd_kcontrol_new *caps[3] = {
4319 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3)
4320 spec->cap_mixer = caps[spec->num_adc_nids - 1];
4323 static int patch_alc880(struct hda_codec *codec)
4325 struct alc_spec *spec;
4329 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4335 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4338 if (board_config < 0) {
4339 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4340 "trying auto-probe from BIOS...\n");
4341 board_config = ALC880_AUTO;
4344 if (board_config == ALC880_AUTO) {
4345 /* automatic parse from the BIOS config */
4346 err = alc880_parse_auto_config(codec);
4352 "hda_codec: Cannot set up configuration "
4353 "from BIOS. Using 3-stack mode...\n");
4354 board_config = ALC880_3ST;
4358 if (board_config != ALC880_AUTO)
4359 setup_preset(spec, &alc880_presets[board_config]);
4361 spec->stream_name_analog = "ALC880 Analog";
4362 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4363 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4364 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4366 spec->stream_name_digital = "ALC880 Digital";
4367 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4368 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4370 if (!spec->adc_nids && spec->input_mux) {
4371 /* check whether NID 0x07 is valid */
4372 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4374 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4375 if (wcap != AC_WID_AUD_IN) {
4376 spec->adc_nids = alc880_adc_nids_alt;
4377 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4379 spec->adc_nids = alc880_adc_nids;
4380 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4383 set_capture_mixer(spec);
4385 spec->vmaster_nid = 0x0c;
4387 codec->patch_ops = alc_patch_ops;
4388 if (board_config == ALC880_AUTO)
4389 spec->init_hook = alc880_auto_init;
4390 #ifdef CONFIG_SND_HDA_POWER_SAVE
4391 if (!spec->loopback.amplist)
4392 spec->loopback.amplist = alc880_loopbacks;
4394 codec->proc_widget_hook = print_realtek_coef;
4404 static hda_nid_t alc260_dac_nids[1] = {
4409 static hda_nid_t alc260_adc_nids[1] = {
4414 static hda_nid_t alc260_adc_nids_alt[1] = {
4419 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4420 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4422 static hda_nid_t alc260_dual_adc_nids[2] = {
4427 #define ALC260_DIGOUT_NID 0x03
4428 #define ALC260_DIGIN_NID 0x06
4430 static struct hda_input_mux alc260_capture_source = {
4434 { "Front Mic", 0x1 },
4440 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4441 * headphone jack and the internal CD lines since these are the only pins at
4442 * which audio can appear. For flexibility, also allow the option of
4443 * recording the mixer output on the second ADC (ADC0 doesn't have a
4444 * connection to the mixer output).
4446 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4450 { "Mic/Line", 0x0 },
4452 { "Headphone", 0x2 },
4458 { "Mic/Line", 0x0 },
4460 { "Headphone", 0x2 },
4467 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4468 * the Fujitsu S702x, but jacks are marked differently.
4470 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4477 { "Headphone", 0x5 },
4486 { "Headphone", 0x6 },
4492 * This is just place-holder, so there's something for alc_build_pcms to look
4493 * at when it calculates the maximum number of channels. ALC260 has no mixer
4494 * element which allows changing the channel mode, so the verb list is
4497 static struct hda_channel_mode alc260_modes[1] = {
4502 /* Mixer combinations
4504 * basic: base_output + input + pc_beep + capture
4505 * HP: base_output + input + capture_alt
4506 * HP_3013: hp_3013 + input + capture
4507 * fujitsu: fujitsu + capture
4508 * acer: acer + capture
4511 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4512 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4513 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4514 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4515 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4516 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4517 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4521 static struct snd_kcontrol_new alc260_input_mixer[] = {
4522 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4523 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4524 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4525 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4526 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4527 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4528 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4529 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4533 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4534 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4535 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4539 /* update HP, line and mono out pins according to the master switch */
4540 static void alc260_hp_master_update(struct hda_codec *codec,
4541 hda_nid_t hp, hda_nid_t line,
4544 struct alc_spec *spec = codec->spec;
4545 unsigned int val = spec->master_sw ? PIN_HP : 0;
4546 /* change HP and line-out pins */
4547 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4549 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4551 /* mono (speaker) depending on the HP jack sense */
4552 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4553 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4557 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4558 struct snd_ctl_elem_value *ucontrol)
4560 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4561 struct alc_spec *spec = codec->spec;
4562 *ucontrol->value.integer.value = spec->master_sw;
4566 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4567 struct snd_ctl_elem_value *ucontrol)
4569 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4570 struct alc_spec *spec = codec->spec;
4571 int val = !!*ucontrol->value.integer.value;
4572 hda_nid_t hp, line, mono;
4574 if (val == spec->master_sw)
4576 spec->master_sw = val;
4577 hp = (kcontrol->private_value >> 16) & 0xff;
4578 line = (kcontrol->private_value >> 8) & 0xff;
4579 mono = kcontrol->private_value & 0xff;
4580 alc260_hp_master_update(codec, hp, line, mono);
4584 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4586 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4587 .name = "Master Playback Switch",
4588 .info = snd_ctl_boolean_mono_info,
4589 .get = alc260_hp_master_sw_get,
4590 .put = alc260_hp_master_sw_put,
4591 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4593 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4594 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4595 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4596 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4597 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4599 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4603 static struct hda_verb alc260_hp_unsol_verbs[] = {
4604 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4608 static void alc260_hp_automute(struct hda_codec *codec)
4610 struct alc_spec *spec = codec->spec;
4611 unsigned int present;
4613 present = snd_hda_codec_read(codec, 0x10, 0,
4614 AC_VERB_GET_PIN_SENSE, 0);
4615 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4616 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4619 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4621 if ((res >> 26) == ALC880_HP_EVENT)
4622 alc260_hp_automute(codec);
4625 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4628 .name = "Master Playback Switch",
4629 .info = snd_ctl_boolean_mono_info,
4630 .get = alc260_hp_master_sw_get,
4631 .put = alc260_hp_master_sw_put,
4632 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4634 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4635 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4636 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4637 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4638 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4639 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4640 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4641 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4645 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4646 .ops = &snd_hda_bind_vol,
4648 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4649 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4650 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4655 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4656 .ops = &snd_hda_bind_sw,
4658 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4659 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4664 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4665 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4666 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4667 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4668 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4672 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4673 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4677 static void alc260_hp_3013_automute(struct hda_codec *codec)
4679 struct alc_spec *spec = codec->spec;
4680 unsigned int present;
4682 present = snd_hda_codec_read(codec, 0x15, 0,
4683 AC_VERB_GET_PIN_SENSE, 0);
4684 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4685 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4688 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4691 if ((res >> 26) == ALC880_HP_EVENT)
4692 alc260_hp_3013_automute(codec);
4695 static void alc260_hp_3012_automute(struct hda_codec *codec)
4697 unsigned int present, bits;
4699 present = snd_hda_codec_read(codec, 0x10, 0,
4700 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4702 bits = present ? 0 : PIN_OUT;
4703 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4705 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4707 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4711 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4714 if ((res >> 26) == ALC880_HP_EVENT)
4715 alc260_hp_3012_automute(codec);
4718 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4719 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4721 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4722 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4723 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4724 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4725 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4726 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4727 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4728 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4729 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4730 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4731 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4732 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4733 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4737 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4738 * versions of the ALC260 don't act on requests to enable mic bias from NID
4739 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4740 * datasheet doesn't mention this restriction. At this stage it's not clear
4741 * whether this behaviour is intentional or is a hardware bug in chip
4742 * revisions available in early 2006. Therefore for now allow the
4743 * "Headphone Jack Mode" control to span all choices, but if it turns out
4744 * that the lack of mic bias for this NID is intentional we could change the
4745 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4747 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4748 * don't appear to make the mic bias available from the "line" jack, even
4749 * though the NID used for this jack (0x14) can supply it. The theory is
4750 * that perhaps Acer have included blocking capacitors between the ALC260
4751 * and the output jack. If this turns out to be the case for all such
4752 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4753 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4755 * The C20x Tablet series have a mono internal speaker which is controlled
4756 * via the chip's Mono sum widget and pin complex, so include the necessary
4757 * controls for such models. On models without a "mono speaker" the control
4758 * won't do anything.
4760 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4761 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4762 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4763 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4764 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4766 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4768 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4769 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4770 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4771 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4772 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4773 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4774 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4775 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4776 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4777 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4781 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4782 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4784 static struct snd_kcontrol_new alc260_will_mixer[] = {
4785 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4786 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4787 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4788 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4789 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4790 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4791 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4792 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4793 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4794 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4795 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4796 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4800 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4801 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4803 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4804 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4805 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4806 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4807 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4808 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4809 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4810 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4811 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4812 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4813 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4818 * initialization verbs
4820 static struct hda_verb alc260_init_verbs[] = {
4821 /* Line In pin widget for input */
4822 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4823 /* CD pin widget for input */
4824 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4825 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4826 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4827 /* Mic2 (front panel) pin widget for input and vref at 80% */
4828 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4829 /* LINE-2 is used for line-out in rear */
4830 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4831 /* select line-out */
4832 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4834 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4836 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4838 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4839 /* mute capture amp left and right */
4840 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4841 /* set connection select to line in (default select for this ADC) */
4842 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4843 /* mute capture amp left and right */
4844 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4845 /* set connection select to line in (default select for this ADC) */
4846 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4847 /* set vol=0 Line-Out mixer amp left and right */
4848 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4849 /* unmute pin widget amp left and right (no gain on this amp) */
4850 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4851 /* set vol=0 HP mixer amp left and right */
4852 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4853 /* unmute pin widget amp left and right (no gain on this amp) */
4854 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4855 /* set vol=0 Mono mixer amp left and right */
4856 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4857 /* unmute pin widget amp left and right (no gain on this amp) */
4858 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4859 /* unmute LINE-2 out pin */
4860 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4861 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4864 /* mute analog inputs */
4865 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4866 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4867 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4868 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4869 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4870 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4871 /* mute Front out path */
4872 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4873 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4874 /* mute Headphone out path */
4875 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4876 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4877 /* mute Mono out path */
4878 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4879 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4883 #if 0 /* should be identical with alc260_init_verbs? */
4884 static struct hda_verb alc260_hp_init_verbs[] = {
4885 /* Headphone and output */
4886 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4888 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4889 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4890 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4891 /* Mic2 (front panel) pin widget for input and vref at 80% */
4892 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4893 /* Line In pin widget for input */
4894 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4895 /* Line-2 pin widget for output */
4896 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4897 /* CD pin widget for input */
4898 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4899 /* unmute amp left and right */
4900 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4901 /* set connection select to line in (default select for this ADC) */
4902 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4903 /* unmute Line-Out mixer amp left and right (volume = 0) */
4904 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4905 /* mute pin widget amp left and right (no gain on this amp) */
4906 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4907 /* unmute HP mixer amp left and right (volume = 0) */
4908 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4909 /* mute pin widget amp left and right (no gain on this amp) */
4910 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4911 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4914 /* mute analog inputs */
4915 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4916 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4917 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4918 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4919 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4920 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4921 /* Unmute Front out path */
4922 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4923 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4924 /* Unmute Headphone out path */
4925 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4926 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4927 /* Unmute Mono out path */
4928 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4929 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4934 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4935 /* Line out and output */
4936 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4938 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4939 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4940 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4941 /* Mic2 (front panel) pin widget for input and vref at 80% */
4942 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4943 /* Line In pin widget for input */
4944 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4945 /* Headphone pin widget for output */
4946 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4947 /* CD pin widget for input */
4948 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4949 /* unmute amp left and right */
4950 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4951 /* set connection select to line in (default select for this ADC) */
4952 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4953 /* unmute Line-Out mixer amp left and right (volume = 0) */
4954 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4955 /* mute pin widget amp left and right (no gain on this amp) */
4956 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4957 /* unmute HP mixer amp left and right (volume = 0) */
4958 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4959 /* mute pin widget amp left and right (no gain on this amp) */
4960 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4961 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4964 /* mute analog inputs */
4965 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4966 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4967 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4968 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4969 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4970 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4971 /* Unmute Front out path */
4972 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4973 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4974 /* Unmute Headphone out path */
4975 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4976 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4977 /* Unmute Mono out path */
4978 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4979 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4983 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4984 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4985 * audio = 0x16, internal speaker = 0x10.
4987 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4988 /* Disable all GPIOs */
4989 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4990 /* Internal speaker is connected to headphone pin */
4991 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4992 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4993 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4994 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4995 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4996 /* Ensure all other unused pins are disabled and muted. */
4997 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4998 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4999 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5000 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5001 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5002 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5003 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5004 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5006 /* Disable digital (SPDIF) pins */
5007 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5008 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5010 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5011 * when acting as an output.
5013 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5015 /* Start with output sum widgets muted and their output gains at min */
5016 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5017 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5018 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5019 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5021 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5022 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5023 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5024 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5026 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5027 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5028 /* Unmute Line1 pin widget output buffer since it starts as an output.
5029 * If the pin mode is changed by the user the pin mode control will
5030 * take care of enabling the pin's input/output buffers as needed.
5031 * Therefore there's no need to enable the input buffer at this
5034 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5035 /* Unmute input buffer of pin widget used for Line-in (no equiv
5038 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5040 /* Mute capture amp left and right */
5041 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5042 /* Set ADC connection select to match default mixer setting - line
5045 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5047 /* Do the same for the second ADC: mute capture input amp and
5048 * set ADC connection to line in (on mic1 pin)
5050 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5051 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5053 /* Mute all inputs to mixer widget (even unconnected ones) */
5054 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5055 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5056 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5057 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5058 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5059 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5060 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5061 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5066 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5067 * similar laptops (adapted from Fujitsu init verbs).
5069 static struct hda_verb alc260_acer_init_verbs[] = {
5070 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5071 * the headphone jack. Turn this on and rely on the standard mute
5072 * methods whenever the user wants to turn these outputs off.
5074 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5075 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5076 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5077 /* Internal speaker/Headphone jack is connected to Line-out pin */
5078 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5079 /* Internal microphone/Mic jack is connected to Mic1 pin */
5080 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5081 /* Line In jack is connected to Line1 pin */
5082 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5083 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5084 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5085 /* Ensure all other unused pins are disabled and muted. */
5086 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5087 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5088 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5089 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5090 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5091 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5092 /* Disable digital (SPDIF) pins */
5093 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5094 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5096 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5097 * bus when acting as outputs.
5099 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5100 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5102 /* Start with output sum widgets muted and their output gains at min */
5103 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5104 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5105 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5106 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5107 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5108 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5109 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5110 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5111 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5113 /* Unmute Line-out pin widget amp left and right
5114 * (no equiv mixer ctrl)
5116 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5117 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5118 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5119 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5120 * inputs. If the pin mode is changed by the user the pin mode control
5121 * will take care of enabling the pin's input/output buffers as needed.
5122 * Therefore there's no need to enable the input buffer at this
5125 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5126 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5128 /* Mute capture amp left and right */
5129 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5130 /* Set ADC connection select to match default mixer setting - mic
5133 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5135 /* Do similar with the second ADC: mute capture input amp and
5136 * set ADC connection to mic to match ALSA's default state.
5138 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5139 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5141 /* Mute all inputs to mixer widget (even unconnected ones) */
5142 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5143 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5144 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5145 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5146 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5147 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5148 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5149 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5154 static struct hda_verb alc260_will_verbs[] = {
5155 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5156 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5157 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5158 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5159 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5160 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5164 static struct hda_verb alc260_replacer_672v_verbs[] = {
5165 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5166 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5167 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5169 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5170 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5171 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5173 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5177 /* toggle speaker-output according to the hp-jack state */
5178 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5180 unsigned int present;
5182 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5183 present = snd_hda_codec_read(codec, 0x0f, 0,
5184 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5186 snd_hda_codec_write_cache(codec, 0x01, 0,
5187 AC_VERB_SET_GPIO_DATA, 1);
5188 snd_hda_codec_write_cache(codec, 0x0f, 0,
5189 AC_VERB_SET_PIN_WIDGET_CONTROL,
5192 snd_hda_codec_write_cache(codec, 0x01, 0,
5193 AC_VERB_SET_GPIO_DATA, 0);
5194 snd_hda_codec_write_cache(codec, 0x0f, 0,
5195 AC_VERB_SET_PIN_WIDGET_CONTROL,
5200 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5203 if ((res >> 26) == ALC880_HP_EVENT)
5204 alc260_replacer_672v_automute(codec);
5207 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5208 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5209 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5210 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5211 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5212 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5213 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5214 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5215 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5216 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5217 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5221 /* Test configuration for debugging, modelled after the ALC880 test
5224 #ifdef CONFIG_SND_DEBUG
5225 static hda_nid_t alc260_test_dac_nids[1] = {
5228 static hda_nid_t alc260_test_adc_nids[2] = {
5231 /* For testing the ALC260, each input MUX needs its own definition since
5232 * the signal assignments are different. This assumes that the first ADC
5235 static struct hda_input_mux alc260_test_capture_sources[2] = {
5239 { "MIC1 pin", 0x0 },
5240 { "MIC2 pin", 0x1 },
5241 { "LINE1 pin", 0x2 },
5242 { "LINE2 pin", 0x3 },
5244 { "LINE-OUT pin", 0x5 },
5245 { "HP-OUT pin", 0x6 },
5251 { "MIC1 pin", 0x0 },
5252 { "MIC2 pin", 0x1 },
5253 { "LINE1 pin", 0x2 },
5254 { "LINE2 pin", 0x3 },
5257 { "LINE-OUT pin", 0x6 },
5258 { "HP-OUT pin", 0x7 },
5262 static struct snd_kcontrol_new alc260_test_mixer[] = {
5263 /* Output driver widgets */
5264 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5265 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5266 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5267 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5268 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5269 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5271 /* Modes for retasking pin widgets
5272 * Note: the ALC260 doesn't seem to act on requests to enable mic
5273 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5274 * mention this restriction. At this stage it's not clear whether
5275 * this behaviour is intentional or is a hardware bug in chip
5276 * revisions available at least up until early 2006. Therefore for
5277 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5278 * choices, but if it turns out that the lack of mic bias for these
5279 * NIDs is intentional we could change their modes from
5280 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5282 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5283 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5284 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5285 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5286 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5287 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5289 /* Loopback mixer controls */
5290 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5291 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5292 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5293 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5294 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5295 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5296 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5297 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5298 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5299 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5300 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
5301 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
5302 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5303 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5304 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5305 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5307 /* Controls for GPIO pins, assuming they are configured as outputs */
5308 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5309 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5310 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5311 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5313 /* Switches to allow the digital IO pins to be enabled. The datasheet
5314 * is ambigious as to which NID is which; testing on laptops which
5315 * make this output available should provide clarification.
5317 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5318 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5320 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5321 * this output to turn on an external amplifier.
5323 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5324 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5328 static struct hda_verb alc260_test_init_verbs[] = {
5329 /* Enable all GPIOs as outputs with an initial value of 0 */
5330 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5331 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5332 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5334 /* Enable retasking pins as output, initially without power amp */
5335 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5336 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5337 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5338 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5339 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5340 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5342 /* Disable digital (SPDIF) pins initially, but users can enable
5343 * them via a mixer switch. In the case of SPDIF-out, this initverb
5344 * payload also sets the generation to 0, output to be in "consumer"
5345 * PCM format, copyright asserted, no pre-emphasis and no validity
5348 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5349 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5351 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5352 * OUT1 sum bus when acting as an output.
5354 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5355 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5356 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5357 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5359 /* Start with output sum widgets muted and their output gains at min */
5360 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5361 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5362 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5363 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5364 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5365 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5366 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5367 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5368 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5370 /* Unmute retasking pin widget output buffers since the default
5371 * state appears to be output. As the pin mode is changed by the
5372 * user the pin mode control will take care of enabling the pin's
5373 * input/output buffers as needed.
5375 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5376 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5377 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5378 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5379 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5380 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5381 /* Also unmute the mono-out pin widget */
5382 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5384 /* Mute capture amp left and right */
5385 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5386 /* Set ADC connection select to match default mixer setting (mic1
5389 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5391 /* Do the same for the second ADC: mute capture input amp and
5392 * set ADC connection to mic1 pin
5394 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5395 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5397 /* Mute all inputs to mixer widget (even unconnected ones) */
5398 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5399 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5400 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5401 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5402 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5403 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5404 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5405 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5411 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5412 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5414 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5415 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5418 * for BIOS auto-configuration
5421 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5422 const char *pfx, int *vol_bits)
5425 unsigned long vol_val, sw_val;
5429 if (nid >= 0x0f && nid < 0x11) {
5430 nid_vol = nid - 0x7;
5431 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5432 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5433 } else if (nid == 0x11) {
5434 nid_vol = nid - 0x7;
5435 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5436 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5437 } else if (nid >= 0x12 && nid <= 0x15) {
5439 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5440 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5444 if (!(*vol_bits & (1 << nid_vol))) {
5445 /* first control for the volume widget */
5446 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5447 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5450 *vol_bits |= (1 << nid_vol);
5452 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5453 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5459 /* add playback controls from the parsed DAC table */
5460 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5461 const struct auto_pin_cfg *cfg)
5467 spec->multiout.num_dacs = 1;
5468 spec->multiout.dac_nids = spec->private_dac_nids;
5469 spec->multiout.dac_nids[0] = 0x02;
5471 nid = cfg->line_out_pins[0];
5473 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5478 nid = cfg->speaker_pins[0];
5480 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5485 nid = cfg->hp_pins[0];
5487 err = alc260_add_playback_controls(spec, nid, "Headphone",
5495 /* create playback/capture controls for input pins */
5496 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5497 const struct auto_pin_cfg *cfg)
5499 struct hda_input_mux *imux = &spec->private_imux[0];
5502 for (i = 0; i < AUTO_PIN_LAST; i++) {
5503 if (cfg->input_pins[i] >= 0x12) {
5504 idx = cfg->input_pins[i] - 0x12;
5505 err = new_analog_input(spec, cfg->input_pins[i],
5506 auto_pin_cfg_labels[i], idx,
5510 imux->items[imux->num_items].label =
5511 auto_pin_cfg_labels[i];
5512 imux->items[imux->num_items].index = idx;
5515 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5516 idx = cfg->input_pins[i] - 0x09;
5517 err = new_analog_input(spec, cfg->input_pins[i],
5518 auto_pin_cfg_labels[i], idx,
5522 imux->items[imux->num_items].label =
5523 auto_pin_cfg_labels[i];
5524 imux->items[imux->num_items].index = idx;
5531 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5532 hda_nid_t nid, int pin_type,
5535 alc_set_pin_output(codec, nid, pin_type);
5536 /* need the manual connection? */
5538 int idx = nid - 0x12;
5539 snd_hda_codec_write(codec, idx + 0x0b, 0,
5540 AC_VERB_SET_CONNECT_SEL, sel_idx);
5544 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5546 struct alc_spec *spec = codec->spec;
5549 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5550 nid = spec->autocfg.line_out_pins[0];
5552 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5553 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5556 nid = spec->autocfg.speaker_pins[0];
5558 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5560 nid = spec->autocfg.hp_pins[0];
5562 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5565 #define ALC260_PIN_CD_NID 0x16
5566 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5568 struct alc_spec *spec = codec->spec;
5571 for (i = 0; i < AUTO_PIN_LAST; i++) {
5572 hda_nid_t nid = spec->autocfg.input_pins[i];
5574 snd_hda_codec_write(codec, nid, 0,
5575 AC_VERB_SET_PIN_WIDGET_CONTROL,
5576 i <= AUTO_PIN_FRONT_MIC ?
5577 PIN_VREF80 : PIN_IN);
5578 if (nid != ALC260_PIN_CD_NID)
5579 snd_hda_codec_write(codec, nid, 0,
5580 AC_VERB_SET_AMP_GAIN_MUTE,
5587 * generic initialization of ADC, input mixers and output mixers
5589 static struct hda_verb alc260_volume_init_verbs[] = {
5591 * Unmute ADC0-1 and set the default input to mic-in
5593 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5594 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5595 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5596 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5598 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5600 * Note: PASD motherboards uses the Line In 2 as the input for
5601 * front panel mic (mic 2)
5603 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5604 /* mute analog inputs */
5605 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5606 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5607 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5608 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5609 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5612 * Set up output mixers (0x08 - 0x0a)
5614 /* set vol=0 to output mixers */
5615 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5616 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5617 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5618 /* set up input amps for analog loopback */
5619 /* Amp Indices: DAC = 0, mixer = 1 */
5620 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5621 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5622 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5623 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5624 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5625 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5630 static int alc260_parse_auto_config(struct hda_codec *codec)
5632 struct alc_spec *spec = codec->spec;
5634 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5636 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5640 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5643 if (!spec->kctls.list)
5644 return 0; /* can't find valid BIOS pin config */
5645 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5649 spec->multiout.max_channels = 2;
5651 if (spec->autocfg.dig_out_pin)
5652 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5653 if (spec->kctls.list)
5654 add_mixer(spec, spec->kctls.list);
5656 add_verb(spec, alc260_volume_init_verbs);
5658 spec->num_mux_defs = 1;
5659 spec->input_mux = &spec->private_imux[0];
5661 store_pin_configs(codec);
5665 /* additional initialization for auto-configuration model */
5666 static void alc260_auto_init(struct hda_codec *codec)
5668 struct alc_spec *spec = codec->spec;
5669 alc260_auto_init_multi_out(codec);
5670 alc260_auto_init_analog_input(codec);
5671 if (spec->unsol_event)
5672 alc_inithook(codec);
5675 #ifdef CONFIG_SND_HDA_POWER_SAVE
5676 static struct hda_amp_list alc260_loopbacks[] = {
5677 { 0x07, HDA_INPUT, 0 },
5678 { 0x07, HDA_INPUT, 1 },
5679 { 0x07, HDA_INPUT, 2 },
5680 { 0x07, HDA_INPUT, 3 },
5681 { 0x07, HDA_INPUT, 4 },
5687 * ALC260 configurations
5689 static const char *alc260_models[ALC260_MODEL_LAST] = {
5690 [ALC260_BASIC] = "basic",
5692 [ALC260_HP_3013] = "hp-3013",
5693 [ALC260_HP_DC7600] = "hp-dc7600",
5694 [ALC260_FUJITSU_S702X] = "fujitsu",
5695 [ALC260_ACER] = "acer",
5696 [ALC260_WILL] = "will",
5697 [ALC260_REPLACER_672V] = "replacer",
5698 #ifdef CONFIG_SND_DEBUG
5699 [ALC260_TEST] = "test",
5701 [ALC260_AUTO] = "auto",
5704 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5705 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5706 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5707 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5708 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5709 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5710 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5711 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5712 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5713 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5714 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5715 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5716 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5717 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5718 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5719 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5720 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5721 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5722 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5726 static struct alc_config_preset alc260_presets[] = {
5728 .mixers = { alc260_base_output_mixer,
5730 alc260_pc_beep_mixer },
5731 .init_verbs = { alc260_init_verbs },
5732 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5733 .dac_nids = alc260_dac_nids,
5734 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5735 .adc_nids = alc260_adc_nids,
5736 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5737 .channel_mode = alc260_modes,
5738 .input_mux = &alc260_capture_source,
5741 .mixers = { alc260_hp_output_mixer,
5742 alc260_input_mixer },
5743 .init_verbs = { alc260_init_verbs,
5744 alc260_hp_unsol_verbs },
5745 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5746 .dac_nids = alc260_dac_nids,
5747 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5748 .adc_nids = alc260_adc_nids_alt,
5749 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5750 .channel_mode = alc260_modes,
5751 .input_mux = &alc260_capture_source,
5752 .unsol_event = alc260_hp_unsol_event,
5753 .init_hook = alc260_hp_automute,
5755 [ALC260_HP_DC7600] = {
5756 .mixers = { alc260_hp_dc7600_mixer,
5757 alc260_input_mixer },
5758 .init_verbs = { alc260_init_verbs,
5759 alc260_hp_dc7600_verbs },
5760 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5761 .dac_nids = alc260_dac_nids,
5762 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5763 .adc_nids = alc260_adc_nids_alt,
5764 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5765 .channel_mode = alc260_modes,
5766 .input_mux = &alc260_capture_source,
5767 .unsol_event = alc260_hp_3012_unsol_event,
5768 .init_hook = alc260_hp_3012_automute,
5770 [ALC260_HP_3013] = {
5771 .mixers = { alc260_hp_3013_mixer,
5772 alc260_input_mixer },
5773 .init_verbs = { alc260_hp_3013_init_verbs,
5774 alc260_hp_3013_unsol_verbs },
5775 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5776 .dac_nids = alc260_dac_nids,
5777 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5778 .adc_nids = alc260_adc_nids_alt,
5779 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5780 .channel_mode = alc260_modes,
5781 .input_mux = &alc260_capture_source,
5782 .unsol_event = alc260_hp_3013_unsol_event,
5783 .init_hook = alc260_hp_3013_automute,
5785 [ALC260_FUJITSU_S702X] = {
5786 .mixers = { alc260_fujitsu_mixer },
5787 .init_verbs = { alc260_fujitsu_init_verbs },
5788 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5789 .dac_nids = alc260_dac_nids,
5790 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5791 .adc_nids = alc260_dual_adc_nids,
5792 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5793 .channel_mode = alc260_modes,
5794 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5795 .input_mux = alc260_fujitsu_capture_sources,
5798 .mixers = { alc260_acer_mixer },
5799 .init_verbs = { alc260_acer_init_verbs },
5800 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5801 .dac_nids = alc260_dac_nids,
5802 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5803 .adc_nids = alc260_dual_adc_nids,
5804 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5805 .channel_mode = alc260_modes,
5806 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5807 .input_mux = alc260_acer_capture_sources,
5810 .mixers = { alc260_will_mixer },
5811 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5812 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5813 .dac_nids = alc260_dac_nids,
5814 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5815 .adc_nids = alc260_adc_nids,
5816 .dig_out_nid = ALC260_DIGOUT_NID,
5817 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5818 .channel_mode = alc260_modes,
5819 .input_mux = &alc260_capture_source,
5821 [ALC260_REPLACER_672V] = {
5822 .mixers = { alc260_replacer_672v_mixer },
5823 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5824 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5825 .dac_nids = alc260_dac_nids,
5826 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5827 .adc_nids = alc260_adc_nids,
5828 .dig_out_nid = ALC260_DIGOUT_NID,
5829 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5830 .channel_mode = alc260_modes,
5831 .input_mux = &alc260_capture_source,
5832 .unsol_event = alc260_replacer_672v_unsol_event,
5833 .init_hook = alc260_replacer_672v_automute,
5835 #ifdef CONFIG_SND_DEBUG
5837 .mixers = { alc260_test_mixer },
5838 .init_verbs = { alc260_test_init_verbs },
5839 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5840 .dac_nids = alc260_test_dac_nids,
5841 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5842 .adc_nids = alc260_test_adc_nids,
5843 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5844 .channel_mode = alc260_modes,
5845 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5846 .input_mux = alc260_test_capture_sources,
5851 static int patch_alc260(struct hda_codec *codec)
5853 struct alc_spec *spec;
5854 int err, board_config;
5856 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5862 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5865 if (board_config < 0) {
5866 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5867 "trying auto-probe from BIOS...\n");
5868 board_config = ALC260_AUTO;
5871 if (board_config == ALC260_AUTO) {
5872 /* automatic parse from the BIOS config */
5873 err = alc260_parse_auto_config(codec);
5879 "hda_codec: Cannot set up configuration "
5880 "from BIOS. Using base mode...\n");
5881 board_config = ALC260_BASIC;
5885 if (board_config != ALC260_AUTO)
5886 setup_preset(spec, &alc260_presets[board_config]);
5888 spec->stream_name_analog = "ALC260 Analog";
5889 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5890 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5892 spec->stream_name_digital = "ALC260 Digital";
5893 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5894 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5896 if (!spec->adc_nids && spec->input_mux) {
5897 /* check whether NID 0x04 is valid */
5898 unsigned int wcap = get_wcaps(codec, 0x04);
5899 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5901 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5902 spec->adc_nids = alc260_adc_nids_alt;
5903 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5905 spec->adc_nids = alc260_adc_nids;
5906 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5909 set_capture_mixer(spec);
5911 spec->vmaster_nid = 0x08;
5913 codec->patch_ops = alc_patch_ops;
5914 if (board_config == ALC260_AUTO)
5915 spec->init_hook = alc260_auto_init;
5916 #ifdef CONFIG_SND_HDA_POWER_SAVE
5917 if (!spec->loopback.amplist)
5918 spec->loopback.amplist = alc260_loopbacks;
5920 codec->proc_widget_hook = print_realtek_coef;
5929 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5930 * configuration. Each pin widget can choose any input DACs and a mixer.
5931 * Each ADC is connected from a mixer of all inputs. This makes possible
5932 * 6-channel independent captures.
5934 * In addition, an independent DAC for the multi-playback (not used in this
5937 #define ALC882_DIGOUT_NID 0x06
5938 #define ALC882_DIGIN_NID 0x0a
5940 static struct hda_channel_mode alc882_ch_modes[1] = {
5944 static hda_nid_t alc882_dac_nids[4] = {
5945 /* front, rear, clfe, rear_surr */
5946 0x02, 0x03, 0x04, 0x05
5949 /* identical with ALC880 */
5950 #define alc882_adc_nids alc880_adc_nids
5951 #define alc882_adc_nids_alt alc880_adc_nids_alt
5953 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5954 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5957 /* FIXME: should be a matrix-type input source selection */
5959 static struct hda_input_mux alc882_capture_source = {
5963 { "Front Mic", 0x1 },
5971 static struct hda_verb alc882_3ST_ch2_init[] = {
5972 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5973 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5974 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5975 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5982 static struct hda_verb alc882_3ST_ch6_init[] = {
5983 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5984 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5985 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5986 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5987 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5988 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5992 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5993 { 2, alc882_3ST_ch2_init },
5994 { 6, alc882_3ST_ch6_init },
6000 static struct hda_verb alc882_sixstack_ch6_init[] = {
6001 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6002 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6003 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6004 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6011 static struct hda_verb alc882_sixstack_ch8_init[] = {
6012 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6013 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6014 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6015 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6019 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6020 { 6, alc882_sixstack_ch6_init },
6021 { 8, alc882_sixstack_ch8_init },
6025 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6031 static struct hda_verb alc885_mbp_ch2_init[] = {
6032 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6033 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6034 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6041 static struct hda_verb alc885_mbp_ch6_init[] = {
6042 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6043 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6044 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6045 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6046 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6050 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6051 { 2, alc885_mbp_ch2_init },
6052 { 6, alc885_mbp_ch6_init },
6056 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6057 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6059 static struct snd_kcontrol_new alc882_base_mixer[] = {
6060 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6061 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6062 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6063 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6064 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6065 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6066 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6067 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6068 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6069 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6070 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6071 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6072 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6073 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6074 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6075 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6076 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6077 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6078 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6079 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6080 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6081 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6082 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6086 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6087 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6088 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6089 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6090 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6091 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6092 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6093 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6094 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
6095 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
6096 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6099 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6100 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6101 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6102 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6103 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6104 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6105 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6106 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6107 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6108 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6109 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6110 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6114 static struct snd_kcontrol_new alc882_targa_mixer[] = {
6115 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6116 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6117 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6118 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6119 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6120 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6121 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6122 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6123 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6124 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6125 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6126 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6127 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6131 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6132 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6134 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6135 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6136 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6137 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6138 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6139 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6140 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6141 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6142 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6143 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6144 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6145 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6146 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6147 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6151 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6152 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6153 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6154 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6155 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6156 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6157 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6158 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6159 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6160 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6161 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6162 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6163 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6167 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6169 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6170 .name = "Channel Mode",
6171 .info = alc_ch_mode_info,
6172 .get = alc_ch_mode_get,
6173 .put = alc_ch_mode_put,
6178 static struct hda_verb alc882_init_verbs[] = {
6179 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6180 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6181 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6182 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6184 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6185 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6186 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6188 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6189 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6190 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6192 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6193 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6194 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6196 /* Front Pin: output 0 (0x0c) */
6197 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6198 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6199 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6200 /* Rear Pin: output 1 (0x0d) */
6201 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6202 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6203 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6204 /* CLFE Pin: output 2 (0x0e) */
6205 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6206 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6207 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6208 /* Side Pin: output 3 (0x0f) */
6209 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6210 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6211 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6212 /* Mic (rear) pin: input vref at 80% */
6213 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6214 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6215 /* Front Mic pin: input vref at 80% */
6216 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6217 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6218 /* Line In pin: input */
6219 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6220 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6221 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6222 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6223 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6224 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6225 /* CD pin widget for input */
6226 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6228 /* FIXME: use matrix-type input source selection */
6229 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6230 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6231 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6232 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6233 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6234 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6236 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6237 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6238 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6239 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6241 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6242 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6243 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6244 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6245 /* ADC1: mute amp left and right */
6246 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6247 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6248 /* ADC2: mute amp left and right */
6249 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6250 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6251 /* ADC3: mute amp left and right */
6252 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6253 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6258 static struct hda_verb alc882_eapd_verbs[] = {
6259 /* change to EAPD mode */
6260 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6261 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6266 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6267 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6268 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6269 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6270 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6271 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6272 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6273 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6277 static struct hda_verb alc882_macpro_init_verbs[] = {
6278 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6279 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6280 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6281 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6282 /* Front Pin: output 0 (0x0c) */
6283 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6284 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6285 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6286 /* Front Mic pin: input vref at 80% */
6287 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6288 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6289 /* Speaker: output */
6290 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6291 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6292 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6293 /* Headphone output (output 0 - 0x0c) */
6294 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6295 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6296 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6298 /* FIXME: use matrix-type input source selection */
6299 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6300 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6301 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6302 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6303 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6304 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6306 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6308 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6309 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6311 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6315 /* ADC1: mute amp left and right */
6316 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6317 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6318 /* ADC2: mute amp left and right */
6319 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6320 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6321 /* ADC3: mute amp left and right */
6322 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6323 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6328 /* Macbook Pro rev3 */
6329 static struct hda_verb alc885_mbp3_init_verbs[] = {
6330 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6333 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6335 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6336 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6337 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6338 /* Front Pin: output 0 (0x0c) */
6339 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6340 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6341 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6342 /* HP Pin: output 0 (0x0d) */
6343 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6344 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6345 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6346 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6347 /* Mic (rear) pin: input vref at 80% */
6348 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6349 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6350 /* Front Mic pin: input vref at 80% */
6351 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6352 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6353 /* Line In pin: use output 1 when in LineOut mode */
6354 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6355 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6356 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6358 /* FIXME: use matrix-type input source selection */
6359 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6360 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6361 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6362 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6363 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6364 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6366 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6367 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6368 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6369 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6371 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6375 /* ADC1: mute amp left and right */
6376 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6377 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6378 /* ADC2: mute amp left and right */
6379 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6380 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6381 /* ADC3: mute amp left and right */
6382 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6383 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6388 /* iMac 24 mixer. */
6389 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6390 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6391 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6395 /* iMac 24 init verbs. */
6396 static struct hda_verb alc885_imac24_init_verbs[] = {
6397 /* Internal speakers: output 0 (0x0c) */
6398 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6399 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6400 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6401 /* Internal speakers: output 0 (0x0c) */
6402 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6403 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6404 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6405 /* Headphone: output 0 (0x0c) */
6406 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6407 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6408 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6409 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6410 /* Front Mic: input vref at 80% */
6411 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6412 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6416 /* Toggle speaker-output according to the hp-jack state */
6417 static void alc885_imac24_automute(struct hda_codec *codec)
6419 unsigned int present;
6421 present = snd_hda_codec_read(codec, 0x14, 0,
6422 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6423 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6424 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6425 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6426 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6429 /* Processes unsolicited events. */
6430 static void alc885_imac24_unsol_event(struct hda_codec *codec,
6433 /* Headphone insertion or removal. */
6434 if ((res >> 26) == ALC880_HP_EVENT)
6435 alc885_imac24_automute(codec);
6438 static void alc885_mbp3_automute(struct hda_codec *codec)
6440 unsigned int present;
6442 present = snd_hda_codec_read(codec, 0x15, 0,
6443 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6444 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6445 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6446 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6447 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6450 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6453 /* Headphone insertion or removal. */
6454 if ((res >> 26) == ALC880_HP_EVENT)
6455 alc885_mbp3_automute(codec);
6459 static struct hda_verb alc882_targa_verbs[] = {
6460 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6461 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6463 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6464 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6466 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6467 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6468 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6470 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6471 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6472 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6473 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6477 /* toggle speaker-output according to the hp-jack state */
6478 static void alc882_targa_automute(struct hda_codec *codec)
6480 unsigned int present;
6482 present = snd_hda_codec_read(codec, 0x14, 0,
6483 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6484 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6485 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6486 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6490 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6492 /* Looks like the unsol event is incompatible with the standard
6493 * definition. 4bit tag is placed at 26 bit!
6495 if (((res >> 26) == ALC880_HP_EVENT)) {
6496 alc882_targa_automute(codec);
6500 static struct hda_verb alc882_asus_a7j_verbs[] = {
6501 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6502 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6504 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6505 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6506 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6508 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6509 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6510 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6512 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6513 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6514 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6518 static struct hda_verb alc882_asus_a7m_verbs[] = {
6519 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6520 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6522 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6523 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6524 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6526 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6527 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6528 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6530 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6531 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6532 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6536 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6538 unsigned int gpiostate, gpiomask, gpiodir;
6540 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6541 AC_VERB_GET_GPIO_DATA, 0);
6544 gpiostate |= (1 << pin);
6546 gpiostate &= ~(1 << pin);
6548 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6549 AC_VERB_GET_GPIO_MASK, 0);
6550 gpiomask |= (1 << pin);
6552 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6553 AC_VERB_GET_GPIO_DIRECTION, 0);
6554 gpiodir |= (1 << pin);
6557 snd_hda_codec_write(codec, codec->afg, 0,
6558 AC_VERB_SET_GPIO_MASK, gpiomask);
6559 snd_hda_codec_write(codec, codec->afg, 0,
6560 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6564 snd_hda_codec_write(codec, codec->afg, 0,
6565 AC_VERB_SET_GPIO_DATA, gpiostate);
6568 /* set up GPIO at initialization */
6569 static void alc885_macpro_init_hook(struct hda_codec *codec)
6571 alc882_gpio_mute(codec, 0, 0);
6572 alc882_gpio_mute(codec, 1, 0);
6575 /* set up GPIO and update auto-muting at initialization */
6576 static void alc885_imac24_init_hook(struct hda_codec *codec)
6578 alc885_macpro_init_hook(codec);
6579 alc885_imac24_automute(codec);
6583 * generic initialization of ADC, input mixers and output mixers
6585 static struct hda_verb alc882_auto_init_verbs[] = {
6587 * Unmute ADC0-2 and set the default input to mic-in
6589 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6591 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6592 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6593 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6594 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6596 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6598 * Note: PASD motherboards uses the Line In 2 as the input for
6599 * front panel mic (mic 2)
6601 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6603 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6604 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6605 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6606 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6609 * Set up output mixers (0x0c - 0x0f)
6611 /* set vol=0 to output mixers */
6612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6613 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6614 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6615 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6616 /* set up input amps for analog loopback */
6617 /* Amp Indices: DAC = 0, mixer = 1 */
6618 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6619 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6620 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6621 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6622 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6623 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6624 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6625 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6626 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6627 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6629 /* FIXME: use matrix-type input source selection */
6630 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6631 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6632 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6633 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6634 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6635 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6637 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6638 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6639 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6640 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6642 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6643 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6644 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6645 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6650 #ifdef CONFIG_SND_HDA_POWER_SAVE
6651 #define alc882_loopbacks alc880_loopbacks
6654 /* pcm configuration: identiacal with ALC880 */
6655 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6656 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6657 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6658 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6661 * configuration and preset
6663 static const char *alc882_models[ALC882_MODEL_LAST] = {
6664 [ALC882_3ST_DIG] = "3stack-dig",
6665 [ALC882_6ST_DIG] = "6stack-dig",
6666 [ALC882_ARIMA] = "arima",
6667 [ALC882_W2JC] = "w2jc",
6668 [ALC882_TARGA] = "targa",
6669 [ALC882_ASUS_A7J] = "asus-a7j",
6670 [ALC882_ASUS_A7M] = "asus-a7m",
6671 [ALC885_MACPRO] = "macpro",
6672 [ALC885_MBP3] = "mbp3",
6673 [ALC885_IMAC24] = "imac24",
6674 [ALC882_AUTO] = "auto",
6677 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6678 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6679 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6680 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6681 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6682 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6683 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6684 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6685 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6686 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6687 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6688 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6689 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6693 static struct alc_config_preset alc882_presets[] = {
6694 [ALC882_3ST_DIG] = {
6695 .mixers = { alc882_base_mixer },
6696 .init_verbs = { alc882_init_verbs },
6697 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6698 .dac_nids = alc882_dac_nids,
6699 .dig_out_nid = ALC882_DIGOUT_NID,
6700 .dig_in_nid = ALC882_DIGIN_NID,
6701 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6702 .channel_mode = alc882_ch_modes,
6704 .input_mux = &alc882_capture_source,
6706 [ALC882_6ST_DIG] = {
6707 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6708 .init_verbs = { alc882_init_verbs },
6709 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6710 .dac_nids = alc882_dac_nids,
6711 .dig_out_nid = ALC882_DIGOUT_NID,
6712 .dig_in_nid = ALC882_DIGIN_NID,
6713 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6714 .channel_mode = alc882_sixstack_modes,
6715 .input_mux = &alc882_capture_source,
6718 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6719 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6720 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6721 .dac_nids = alc882_dac_nids,
6722 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6723 .channel_mode = alc882_sixstack_modes,
6724 .input_mux = &alc882_capture_source,
6727 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6728 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6729 alc880_gpio1_init_verbs },
6730 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6731 .dac_nids = alc882_dac_nids,
6732 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6733 .channel_mode = alc880_threestack_modes,
6735 .input_mux = &alc882_capture_source,
6736 .dig_out_nid = ALC882_DIGOUT_NID,
6739 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6740 .init_verbs = { alc885_mbp3_init_verbs,
6741 alc880_gpio1_init_verbs },
6742 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6743 .dac_nids = alc882_dac_nids,
6744 .channel_mode = alc885_mbp_6ch_modes,
6745 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6746 .input_mux = &alc882_capture_source,
6747 .dig_out_nid = ALC882_DIGOUT_NID,
6748 .dig_in_nid = ALC882_DIGIN_NID,
6749 .unsol_event = alc885_mbp3_unsol_event,
6750 .init_hook = alc885_mbp3_automute,
6753 .mixers = { alc882_macpro_mixer },
6754 .init_verbs = { alc882_macpro_init_verbs },
6755 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6756 .dac_nids = alc882_dac_nids,
6757 .dig_out_nid = ALC882_DIGOUT_NID,
6758 .dig_in_nid = ALC882_DIGIN_NID,
6759 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6760 .channel_mode = alc882_ch_modes,
6761 .input_mux = &alc882_capture_source,
6762 .init_hook = alc885_macpro_init_hook,
6765 .mixers = { alc885_imac24_mixer },
6766 .init_verbs = { alc885_imac24_init_verbs },
6767 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6768 .dac_nids = alc882_dac_nids,
6769 .dig_out_nid = ALC882_DIGOUT_NID,
6770 .dig_in_nid = ALC882_DIGIN_NID,
6771 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6772 .channel_mode = alc882_ch_modes,
6773 .input_mux = &alc882_capture_source,
6774 .unsol_event = alc885_imac24_unsol_event,
6775 .init_hook = alc885_imac24_init_hook,
6778 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
6779 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6780 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6781 .dac_nids = alc882_dac_nids,
6782 .dig_out_nid = ALC882_DIGOUT_NID,
6783 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6784 .adc_nids = alc882_adc_nids,
6785 .capsrc_nids = alc882_capsrc_nids,
6786 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6787 .channel_mode = alc882_3ST_6ch_modes,
6789 .input_mux = &alc882_capture_source,
6790 .unsol_event = alc882_targa_unsol_event,
6791 .init_hook = alc882_targa_automute,
6793 [ALC882_ASUS_A7J] = {
6794 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
6795 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6796 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6797 .dac_nids = alc882_dac_nids,
6798 .dig_out_nid = ALC882_DIGOUT_NID,
6799 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6800 .adc_nids = alc882_adc_nids,
6801 .capsrc_nids = alc882_capsrc_nids,
6802 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6803 .channel_mode = alc882_3ST_6ch_modes,
6805 .input_mux = &alc882_capture_source,
6807 [ALC882_ASUS_A7M] = {
6808 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6809 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6810 alc880_gpio1_init_verbs,
6811 alc882_asus_a7m_verbs },
6812 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6813 .dac_nids = alc882_dac_nids,
6814 .dig_out_nid = ALC882_DIGOUT_NID,
6815 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6816 .channel_mode = alc880_threestack_modes,
6818 .input_mux = &alc882_capture_source,
6827 PINFIX_ABIT_AW9D_MAX
6830 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6831 { 0x15, 0x01080104 }, /* side */
6832 { 0x16, 0x01011012 }, /* rear */
6833 { 0x17, 0x01016011 }, /* clfe */
6837 static const struct alc_pincfg *alc882_pin_fixes[] = {
6838 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6841 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6842 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6847 * BIOS auto configuration
6849 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6850 hda_nid_t nid, int pin_type,
6854 struct alc_spec *spec = codec->spec;
6857 alc_set_pin_output(codec, nid, pin_type);
6858 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6861 idx = spec->multiout.dac_nids[dac_idx] - 2;
6862 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6866 static void alc882_auto_init_multi_out(struct hda_codec *codec)
6868 struct alc_spec *spec = codec->spec;
6871 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6872 for (i = 0; i <= HDA_SIDE; i++) {
6873 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6874 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6876 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6881 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6883 struct alc_spec *spec = codec->spec;
6886 pin = spec->autocfg.hp_pins[0];
6887 if (pin) /* connect to front */
6889 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6890 pin = spec->autocfg.speaker_pins[0];
6892 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6895 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6896 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6898 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6900 struct alc_spec *spec = codec->spec;
6903 for (i = 0; i < AUTO_PIN_LAST; i++) {
6904 hda_nid_t nid = spec->autocfg.input_pins[i];
6909 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6910 unsigned int pincap;
6911 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6912 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6916 snd_hda_codec_write(codec, nid, 0,
6917 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6918 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6919 snd_hda_codec_write(codec, nid, 0,
6920 AC_VERB_SET_AMP_GAIN_MUTE,
6925 static void alc882_auto_init_input_src(struct hda_codec *codec)
6927 struct alc_spec *spec = codec->spec;
6930 for (c = 0; c < spec->num_adc_nids; c++) {
6931 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6932 hda_nid_t nid = spec->capsrc_nids[c];
6933 unsigned int mux_idx;
6934 const struct hda_input_mux *imux;
6935 int conns, mute, idx, item;
6937 conns = snd_hda_get_connections(codec, nid, conn_list,
6938 ARRAY_SIZE(conn_list));
6941 mux_idx = c >= spec->num_mux_defs ? 0 : c;
6942 imux = &spec->input_mux[mux_idx];
6943 for (idx = 0; idx < conns; idx++) {
6944 /* if the current connection is the selected one,
6945 * unmute it as default - otherwise mute it
6947 mute = AMP_IN_MUTE(idx);
6948 for (item = 0; item < imux->num_items; item++) {
6949 if (imux->items[item].index == idx) {
6950 if (spec->cur_mux[c] == item)
6951 mute = AMP_IN_UNMUTE(idx);
6955 /* check if we have a selector or mixer
6956 * we could check for the widget type instead, but
6957 * just check for Amp-In presence (in case of mixer
6958 * without amp-in there is something wrong, this
6959 * function shouldn't be used or capsrc nid is wrong)
6961 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
6962 snd_hda_codec_write(codec, nid, 0,
6963 AC_VERB_SET_AMP_GAIN_MUTE,
6965 else if (mute != AMP_IN_MUTE(idx))
6966 snd_hda_codec_write(codec, nid, 0,
6967 AC_VERB_SET_CONNECT_SEL,
6973 /* add mic boosts if needed */
6974 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6976 struct alc_spec *spec = codec->spec;
6980 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6981 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6982 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6984 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6988 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6989 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6990 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6992 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6999 /* almost identical with ALC880 parser... */
7000 static int alc882_parse_auto_config(struct hda_codec *codec)
7002 struct alc_spec *spec = codec->spec;
7003 int err = alc880_parse_auto_config(codec);
7008 return 0; /* no config found */
7010 err = alc_auto_add_mic_boost(codec);
7014 /* hack - override the init verbs */
7015 spec->init_verbs[0] = alc882_auto_init_verbs;
7017 return 1; /* config found */
7020 /* additional initialization for auto-configuration model */
7021 static void alc882_auto_init(struct hda_codec *codec)
7023 struct alc_spec *spec = codec->spec;
7024 alc882_auto_init_multi_out(codec);
7025 alc882_auto_init_hp_out(codec);
7026 alc882_auto_init_analog_input(codec);
7027 alc882_auto_init_input_src(codec);
7028 if (spec->unsol_event)
7029 alc_inithook(codec);
7032 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7034 static int patch_alc882(struct hda_codec *codec)
7036 struct alc_spec *spec;
7037 int err, board_config;
7039 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7045 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7049 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7050 /* Pick up systems that don't supply PCI SSID */
7051 switch (codec->subsystem_id) {
7052 case 0x106b0c00: /* Mac Pro */
7053 board_config = ALC885_MACPRO;
7055 case 0x106b1000: /* iMac 24 */
7056 case 0x106b2800: /* AppleTV */
7057 case 0x106b3e00: /* iMac 24 Aluminium */
7058 board_config = ALC885_IMAC24;
7060 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7061 case 0x106b00a4: /* MacbookPro4,1 */
7062 case 0x106b2c00: /* Macbook Pro rev3 */
7063 case 0x106b3600: /* Macbook 3.1 */
7064 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7065 board_config = ALC885_MBP3;
7068 /* ALC889A is handled better as ALC888-compatible */
7069 if (codec->revision_id == 0x100101 ||
7070 codec->revision_id == 0x100103) {
7072 return patch_alc883(codec);
7074 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
7075 "trying auto-probe from BIOS...\n");
7076 board_config = ALC882_AUTO;
7080 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7082 if (board_config == ALC882_AUTO) {
7083 /* automatic parse from the BIOS config */
7084 err = alc882_parse_auto_config(codec);
7090 "hda_codec: Cannot set up configuration "
7091 "from BIOS. Using base mode...\n");
7092 board_config = ALC882_3ST_DIG;
7096 if (board_config != ALC882_AUTO)
7097 setup_preset(spec, &alc882_presets[board_config]);
7099 if (codec->vendor_id == 0x10ec0885) {
7100 spec->stream_name_analog = "ALC885 Analog";
7101 spec->stream_name_digital = "ALC885 Digital";
7103 spec->stream_name_analog = "ALC882 Analog";
7104 spec->stream_name_digital = "ALC882 Digital";
7107 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7108 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7109 /* FIXME: setup DAC5 */
7110 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7111 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7113 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7114 spec->stream_digital_capture = &alc882_pcm_digital_capture;
7116 spec->capture_style = CAPT_MIX; /* matrix-style capture */
7117 if (!spec->adc_nids && spec->input_mux) {
7118 /* check whether NID 0x07 is valid */
7119 unsigned int wcap = get_wcaps(codec, 0x07);
7121 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7122 if (wcap != AC_WID_AUD_IN) {
7123 spec->adc_nids = alc882_adc_nids_alt;
7124 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7125 spec->capsrc_nids = alc882_capsrc_nids_alt;
7127 spec->adc_nids = alc882_adc_nids;
7128 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7129 spec->capsrc_nids = alc882_capsrc_nids;
7132 set_capture_mixer(spec);
7134 spec->vmaster_nid = 0x0c;
7136 codec->patch_ops = alc_patch_ops;
7137 if (board_config == ALC882_AUTO)
7138 spec->init_hook = alc882_auto_init;
7139 #ifdef CONFIG_SND_HDA_POWER_SAVE
7140 if (!spec->loopback.amplist)
7141 spec->loopback.amplist = alc882_loopbacks;
7143 codec->proc_widget_hook = print_realtek_coef;
7151 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7152 * configuration. Each pin widget can choose any input DACs and a mixer.
7153 * Each ADC is connected from a mixer of all inputs. This makes possible
7154 * 6-channel independent captures.
7156 * In addition, an independent DAC for the multi-playback (not used in this
7159 #define ALC883_DIGOUT_NID 0x06
7160 #define ALC883_DIGIN_NID 0x0a
7162 #define ALC1200_DIGOUT_NID 0x10
7164 static hda_nid_t alc883_dac_nids[4] = {
7165 /* front, rear, clfe, rear_surr */
7166 0x02, 0x03, 0x04, 0x05
7169 static hda_nid_t alc883_adc_nids[2] = {
7174 static hda_nid_t alc883_adc_nids_alt[1] = {
7179 static hda_nid_t alc883_adc_nids_rev[2] = {
7184 #define alc889_adc_nids alc880_adc_nids
7186 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7188 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7190 #define alc889_capsrc_nids alc882_capsrc_nids
7193 /* FIXME: should be a matrix-type input source selection */
7195 static struct hda_input_mux alc883_capture_source = {
7199 { "Front Mic", 0x1 },
7205 static struct hda_input_mux alc883_3stack_6ch_intel = {
7209 { "Front Mic", 0x0 },
7215 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7223 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7233 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7241 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7245 { "Front Mic", 0x1 },
7250 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7261 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7268 static struct hda_verb alc883_3ST_ch2_init[] = {
7269 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7270 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7271 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7272 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7279 static struct hda_verb alc883_3ST_ch4_init[] = {
7280 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7281 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7282 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7283 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7284 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7291 static struct hda_verb alc883_3ST_ch6_init[] = {
7292 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7293 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7294 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7295 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7296 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7297 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7301 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7302 { 2, alc883_3ST_ch2_init },
7303 { 4, alc883_3ST_ch4_init },
7304 { 6, alc883_3ST_ch6_init },
7310 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7311 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7312 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7313 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7314 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7321 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7322 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7323 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7324 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7325 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7326 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7333 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7334 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7335 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7336 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7337 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7338 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7339 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7343 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7344 { 2, alc883_3ST_ch2_intel_init },
7345 { 4, alc883_3ST_ch4_intel_init },
7346 { 6, alc883_3ST_ch6_intel_init },
7352 static struct hda_verb alc883_sixstack_ch6_init[] = {
7353 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7354 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7355 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7356 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7363 static struct hda_verb alc883_sixstack_ch8_init[] = {
7364 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7365 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7366 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7367 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7371 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7372 { 6, alc883_sixstack_ch6_init },
7373 { 8, alc883_sixstack_ch8_init },
7376 static struct hda_verb alc883_medion_eapd_verbs[] = {
7377 /* eanable EAPD on medion laptop */
7378 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7379 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7383 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7384 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7387 static struct snd_kcontrol_new alc883_base_mixer[] = {
7388 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7389 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7390 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7391 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7392 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7393 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7394 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7395 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7396 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7397 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7398 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7399 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7400 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7401 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7402 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7404 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7406 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7407 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7408 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7409 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7410 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7414 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7415 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7416 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7417 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7418 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7419 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7420 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7421 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7422 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7423 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7424 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7425 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7426 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7427 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7431 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7432 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7433 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7434 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7435 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7437 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7438 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7439 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7440 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7441 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7445 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7446 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7447 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7448 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7449 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7450 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7451 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7452 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7453 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7454 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7455 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7459 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7460 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7461 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7462 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7463 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7464 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7465 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7466 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7467 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7468 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7469 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7470 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7471 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7472 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7473 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7474 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7478 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7479 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7480 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7481 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7482 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7483 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7484 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7485 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7486 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7487 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7488 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7489 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7490 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7491 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7492 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7493 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7494 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7495 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7496 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7497 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7498 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7499 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7503 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7504 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7505 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7506 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7507 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7508 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7510 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7511 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7512 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7513 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7514 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7515 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7516 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7517 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7518 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7519 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7520 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7521 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7522 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7523 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7524 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7525 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7529 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7530 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7531 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7532 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7533 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7534 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7535 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7536 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7537 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7538 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7539 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7540 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7541 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7542 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7543 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7544 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7545 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7546 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7547 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7548 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7549 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7550 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7554 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7555 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7556 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7557 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7558 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7559 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7560 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7561 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7562 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7563 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7564 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7565 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7566 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7567 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7568 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7569 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7570 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7574 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7575 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7576 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7577 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7578 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7579 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7580 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7581 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7582 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7583 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7584 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7585 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7589 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7590 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7591 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7592 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7593 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7594 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7595 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7596 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7597 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7601 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7602 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7603 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7604 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7605 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7606 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7607 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7608 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7609 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7610 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7614 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7615 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7616 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7617 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7618 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7619 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7620 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7621 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7622 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7623 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7627 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7628 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7629 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7630 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7631 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7632 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7633 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7634 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7635 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7639 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7640 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7641 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7642 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7643 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7644 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7645 0x0d, 1, 0x0, HDA_OUTPUT),
7646 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7647 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7648 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7649 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7650 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7651 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7652 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7653 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7654 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7655 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7656 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7657 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7658 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7659 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7660 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7661 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7662 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7666 static struct hda_bind_ctls alc883_bind_cap_vol = {
7667 .ops = &snd_hda_bind_vol,
7669 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7670 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7675 static struct hda_bind_ctls alc883_bind_cap_switch = {
7676 .ops = &snd_hda_bind_sw,
7678 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7679 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7684 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7685 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7686 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7687 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7688 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7689 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7690 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7691 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7692 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7696 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7697 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7698 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7700 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7701 /* .name = "Capture Source", */
7702 .name = "Input Source",
7704 .info = alc_mux_enum_info,
7705 .get = alc_mux_enum_get,
7706 .put = alc_mux_enum_put,
7711 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7713 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7714 .name = "Channel Mode",
7715 .info = alc_ch_mode_info,
7716 .get = alc_ch_mode_get,
7717 .put = alc_ch_mode_put,
7722 static struct hda_verb alc883_init_verbs[] = {
7723 /* ADC1: mute amp left and right */
7724 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7725 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7726 /* ADC2: mute amp left and right */
7727 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7728 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7729 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7730 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7731 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7732 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7734 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7735 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7736 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7738 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7739 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7740 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7742 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7743 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7744 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7746 /* mute analog input loopbacks */
7747 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7748 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7749 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7750 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7751 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7753 /* Front Pin: output 0 (0x0c) */
7754 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7755 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7756 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7757 /* Rear Pin: output 1 (0x0d) */
7758 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7759 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7760 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7761 /* CLFE Pin: output 2 (0x0e) */
7762 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7763 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7764 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7765 /* Side Pin: output 3 (0x0f) */
7766 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7767 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7768 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7769 /* Mic (rear) pin: input vref at 80% */
7770 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7771 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7772 /* Front Mic pin: input vref at 80% */
7773 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7774 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7775 /* Line In pin: input */
7776 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7777 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7778 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7779 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7780 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7781 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7782 /* CD pin widget for input */
7783 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7785 /* FIXME: use matrix-type input source selection */
7786 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7788 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7789 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7790 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7791 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7793 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7794 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7795 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7796 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7800 /* toggle speaker-output according to the hp-jack state */
7801 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7803 unsigned int present;
7805 present = snd_hda_codec_read(codec, 0x15, 0,
7806 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7807 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7808 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7809 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7810 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7813 /* auto-toggle front mic */
7815 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7817 unsigned int present;
7820 present = snd_hda_codec_read(codec, 0x18, 0,
7821 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7822 bits = present ? HDA_AMP_MUTE : 0;
7823 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7827 static void alc883_mitac_automute(struct hda_codec *codec)
7829 alc883_mitac_hp_automute(codec);
7830 /* alc883_mitac_mic_automute(codec); */
7833 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7836 switch (res >> 26) {
7837 case ALC880_HP_EVENT:
7838 alc883_mitac_hp_automute(codec);
7840 case ALC880_MIC_EVENT:
7841 /* alc883_mitac_mic_automute(codec); */
7846 static struct hda_verb alc883_mitac_verbs[] = {
7848 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7849 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7851 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7852 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7854 /* enable unsolicited event */
7855 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7856 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7861 static struct hda_verb alc883_clevo_m720_verbs[] = {
7863 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7864 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7866 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7867 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7869 /* enable unsolicited event */
7870 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7871 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7876 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7878 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7879 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7881 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7882 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7884 /* enable unsolicited event */
7885 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7890 static struct hda_verb alc883_tagra_verbs[] = {
7891 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7892 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7894 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7895 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7897 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7898 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7899 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7901 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7902 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7903 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7904 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7909 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7910 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7911 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7912 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7916 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7917 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7918 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7919 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7920 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7924 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7925 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7926 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7927 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7928 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7929 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7933 static struct hda_verb alc883_haier_w66_verbs[] = {
7934 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7935 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7937 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7939 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7940 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7941 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7942 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7946 static struct hda_verb alc888_lenovo_sky_verbs[] = {
7947 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7948 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7949 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7950 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7951 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7952 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7953 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7954 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7958 static struct hda_verb alc888_3st_hp_verbs[] = {
7959 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7960 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7961 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7965 static struct hda_verb alc888_6st_dell_verbs[] = {
7966 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7970 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7971 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7972 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7973 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7974 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7978 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7979 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7980 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7981 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7982 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7986 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7987 { 2, alc888_3st_hp_2ch_init },
7988 { 6, alc888_3st_hp_6ch_init },
7991 /* toggle front-jack and RCA according to the hp-jack state */
7992 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7994 unsigned int present;
7996 present = snd_hda_codec_read(codec, 0x1b, 0,
7997 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7998 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7999 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8000 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8001 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8004 /* toggle RCA according to the front-jack state */
8005 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8007 unsigned int present;
8009 present = snd_hda_codec_read(codec, 0x14, 0,
8010 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8011 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8012 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8015 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8018 if ((res >> 26) == ALC880_HP_EVENT)
8019 alc888_lenovo_ms7195_front_automute(codec);
8020 if ((res >> 26) == ALC880_FRONT_EVENT)
8021 alc888_lenovo_ms7195_rca_automute(codec);
8024 static struct hda_verb alc883_medion_md2_verbs[] = {
8025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8026 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8028 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8030 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8034 /* toggle speaker-output according to the hp-jack state */
8035 static void alc883_medion_md2_automute(struct hda_codec *codec)
8037 unsigned int present;
8039 present = snd_hda_codec_read(codec, 0x14, 0,
8040 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8041 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8042 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8045 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
8048 if ((res >> 26) == ALC880_HP_EVENT)
8049 alc883_medion_md2_automute(codec);
8052 /* toggle speaker-output according to the hp-jack state */
8053 static void alc883_tagra_automute(struct hda_codec *codec)
8055 unsigned int present;
8058 present = snd_hda_codec_read(codec, 0x14, 0,
8059 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8060 bits = present ? HDA_AMP_MUTE : 0;
8061 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
8062 HDA_AMP_MUTE, bits);
8063 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8067 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
8069 if ((res >> 26) == ALC880_HP_EVENT)
8070 alc883_tagra_automute(codec);
8073 /* toggle speaker-output according to the hp-jack state */
8074 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
8076 unsigned int present;
8079 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
8080 & AC_PINSENSE_PRESENCE;
8081 bits = present ? HDA_AMP_MUTE : 0;
8082 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8083 HDA_AMP_MUTE, bits);
8086 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8088 unsigned int present;
8090 present = snd_hda_codec_read(codec, 0x18, 0,
8091 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8092 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8093 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8096 static void alc883_clevo_m720_automute(struct hda_codec *codec)
8098 alc883_clevo_m720_hp_automute(codec);
8099 alc883_clevo_m720_mic_automute(codec);
8102 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8105 switch (res >> 26) {
8106 case ALC880_HP_EVENT:
8107 alc883_clevo_m720_hp_automute(codec);
8109 case ALC880_MIC_EVENT:
8110 alc883_clevo_m720_mic_automute(codec);
8115 /* toggle speaker-output according to the hp-jack state */
8116 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
8118 unsigned int present;
8121 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8122 & AC_PINSENSE_PRESENCE;
8123 bits = present ? HDA_AMP_MUTE : 0;
8124 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8125 HDA_AMP_MUTE, bits);
8128 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
8131 if ((res >> 26) == ALC880_HP_EVENT)
8132 alc883_2ch_fujitsu_pi2515_automute(codec);
8135 static void alc883_haier_w66_automute(struct hda_codec *codec)
8137 unsigned int present;
8140 present = snd_hda_codec_read(codec, 0x1b, 0,
8141 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8142 bits = present ? 0x80 : 0;
8143 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8147 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
8150 if ((res >> 26) == ALC880_HP_EVENT)
8151 alc883_haier_w66_automute(codec);
8154 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8156 unsigned int present;
8159 present = snd_hda_codec_read(codec, 0x14, 0,
8160 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8161 bits = present ? HDA_AMP_MUTE : 0;
8162 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8163 HDA_AMP_MUTE, bits);
8166 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8168 unsigned int present;
8171 present = snd_hda_codec_read(codec, 0x1b, 0,
8172 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8173 bits = present ? HDA_AMP_MUTE : 0;
8174 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8175 HDA_AMP_MUTE, bits);
8176 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8177 HDA_AMP_MUTE, bits);
8180 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8183 if ((res >> 26) == ALC880_HP_EVENT)
8184 alc883_lenovo_101e_all_automute(codec);
8185 if ((res >> 26) == ALC880_FRONT_EVENT)
8186 alc883_lenovo_101e_ispeaker_automute(codec);
8189 /* toggle speaker-output according to the hp-jack state */
8190 static void alc883_acer_aspire_automute(struct hda_codec *codec)
8192 unsigned int present;
8194 present = snd_hda_codec_read(codec, 0x14, 0,
8195 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8196 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8197 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8198 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8199 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8202 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
8205 if ((res >> 26) == ALC880_HP_EVENT)
8206 alc883_acer_aspire_automute(codec);
8209 static struct hda_verb alc883_acer_eapd_verbs[] = {
8210 /* HP Pin: output 0 (0x0c) */
8211 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8212 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8213 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8214 /* Front Pin: output 0 (0x0c) */
8215 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8216 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8217 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8218 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8219 /* eanable EAPD on medion laptop */
8220 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8221 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8222 /* enable unsolicited event */
8223 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8227 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8229 unsigned int present;
8231 present = snd_hda_codec_read(codec, 0x1b, 0,
8232 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8233 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8234 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8235 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8236 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8237 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8238 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8239 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8240 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8243 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8246 switch (res >> 26) {
8247 case ALC880_HP_EVENT:
8248 printk("hp_event\n");
8249 alc888_6st_dell_front_automute(codec);
8254 static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8257 unsigned int present;
8259 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8260 present = snd_hda_codec_read(codec, 0x1b, 0,
8261 AC_VERB_GET_PIN_SENSE, 0);
8262 present = (present & 0x80000000) != 0;
8264 /* mute internal speaker */
8265 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8266 HDA_AMP_MUTE, HDA_AMP_MUTE);
8267 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8268 HDA_AMP_MUTE, HDA_AMP_MUTE);
8269 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8270 HDA_AMP_MUTE, HDA_AMP_MUTE);
8271 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8272 HDA_AMP_MUTE, HDA_AMP_MUTE);
8273 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8274 HDA_AMP_MUTE, HDA_AMP_MUTE);
8276 /* unmute internal speaker if necessary */
8277 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8278 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8279 HDA_AMP_MUTE, mute);
8280 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8281 HDA_AMP_MUTE, mute);
8282 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8283 HDA_AMP_MUTE, mute);
8284 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8285 HDA_AMP_MUTE, mute);
8286 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8287 HDA_AMP_MUTE, mute);
8291 static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8294 if ((res >> 26) == ALC880_HP_EVENT)
8295 alc888_lenovo_sky_front_automute(codec);
8299 * generic initialization of ADC, input mixers and output mixers
8301 static struct hda_verb alc883_auto_init_verbs[] = {
8303 * Unmute ADC0-2 and set the default input to mic-in
8305 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8306 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8307 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8308 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8310 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8312 * Note: PASD motherboards uses the Line In 2 as the input for
8313 * front panel mic (mic 2)
8315 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8316 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8317 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8318 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8319 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8320 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8323 * Set up output mixers (0x0c - 0x0f)
8325 /* set vol=0 to output mixers */
8326 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8327 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8328 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8329 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8330 /* set up input amps for analog loopback */
8331 /* Amp Indices: DAC = 0, mixer = 1 */
8332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8333 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8334 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8335 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8336 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8337 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8338 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8339 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8340 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8341 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8343 /* FIXME: use matrix-type input source selection */
8344 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8346 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8347 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8348 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8349 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8350 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8352 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8353 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8354 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8355 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8356 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8361 static struct hda_verb alc888_asus_m90v_verbs[] = {
8362 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8363 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8364 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8365 /* enable unsolicited event */
8366 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8367 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8371 static void alc883_nb_mic_automute(struct hda_codec *codec)
8373 unsigned int present;
8375 present = snd_hda_codec_read(codec, 0x18, 0,
8376 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8377 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8378 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8379 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8380 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8383 static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8385 unsigned int present;
8388 present = snd_hda_codec_read(codec, 0x1b, 0,
8389 AC_VERB_GET_PIN_SENSE, 0)
8390 & AC_PINSENSE_PRESENCE;
8391 bits = present ? 0 : PIN_OUT;
8392 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8394 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8396 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8400 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8403 switch (res >> 26) {
8404 case ALC880_HP_EVENT:
8405 alc883_M90V_speaker_automute(codec);
8407 case ALC880_MIC_EVENT:
8408 alc883_nb_mic_automute(codec);
8413 static void alc883_mode2_inithook(struct hda_codec *codec)
8415 alc883_M90V_speaker_automute(codec);
8416 alc883_nb_mic_automute(codec);
8419 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8420 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8421 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8422 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8423 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8424 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8425 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8426 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8427 /* enable unsolicited event */
8428 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8432 static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8434 unsigned int present;
8437 present = snd_hda_codec_read(codec, 0x14, 0,
8438 AC_VERB_GET_PIN_SENSE, 0)
8439 & AC_PINSENSE_PRESENCE;
8440 bits = present ? 0 : PIN_OUT;
8441 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8445 static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8448 switch (res >> 26) {
8449 case ALC880_HP_EVENT:
8450 alc883_eee1601_speaker_automute(codec);
8455 static void alc883_eee1601_inithook(struct hda_codec *codec)
8457 alc883_eee1601_speaker_automute(codec);
8460 #ifdef CONFIG_SND_HDA_POWER_SAVE
8461 #define alc883_loopbacks alc880_loopbacks
8464 /* pcm configuration: identiacal with ALC880 */
8465 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8466 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8467 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8468 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8469 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8472 * configuration and preset
8474 static const char *alc883_models[ALC883_MODEL_LAST] = {
8475 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8476 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8477 [ALC883_3ST_6ch] = "3stack-6ch",
8478 [ALC883_6ST_DIG] = "6stack-dig",
8479 [ALC883_TARGA_DIG] = "targa-dig",
8480 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8481 [ALC883_ACER] = "acer",
8482 [ALC883_ACER_ASPIRE] = "acer-aspire",
8483 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8484 [ALC883_MEDION] = "medion",
8485 [ALC883_MEDION_MD2] = "medion-md2",
8486 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8487 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8488 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8489 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8490 [ALC888_LENOVO_SKY] = "lenovo-sky",
8491 [ALC883_HAIER_W66] = "haier-w66",
8492 [ALC888_3ST_HP] = "3stack-hp",
8493 [ALC888_6ST_DELL] = "6stack-dell",
8494 [ALC883_MITAC] = "mitac",
8495 [ALC883_CLEVO_M720] = "clevo-m720",
8496 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8497 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8498 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8499 [ALC1200_ASUS_P5Q] = "asus-p5q",
8500 [ALC883_AUTO] = "auto",
8503 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8504 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8505 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8506 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8507 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8508 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8509 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8510 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8511 ALC888_ACER_ASPIRE_4930G),
8512 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8513 ALC888_ACER_ASPIRE_4930G),
8514 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8515 ALC888_ACER_ASPIRE_4930G),
8516 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8517 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8518 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8519 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8520 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8521 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8522 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8523 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8524 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8525 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8526 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8527 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8528 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8529 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8530 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8531 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8532 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8533 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8534 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8535 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8536 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8537 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8538 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8539 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8540 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8541 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8542 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8543 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8544 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8545 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8546 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8547 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8548 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8549 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8550 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8551 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8552 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8553 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8554 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8555 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8556 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8557 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8558 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8559 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8560 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8561 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8562 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8563 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8564 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8565 SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530",
8566 ALC888_FUJITSU_XA3530),
8567 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8568 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8569 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8570 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8571 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8572 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8573 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8574 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8575 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8576 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8577 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8578 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8579 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8580 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8584 static struct alc_config_preset alc883_presets[] = {
8585 [ALC883_3ST_2ch_DIG] = {
8586 .mixers = { alc883_3ST_2ch_mixer },
8587 .init_verbs = { alc883_init_verbs },
8588 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8589 .dac_nids = alc883_dac_nids,
8590 .dig_out_nid = ALC883_DIGOUT_NID,
8591 .dig_in_nid = ALC883_DIGIN_NID,
8592 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8593 .channel_mode = alc883_3ST_2ch_modes,
8594 .input_mux = &alc883_capture_source,
8596 [ALC883_3ST_6ch_DIG] = {
8597 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8598 .init_verbs = { alc883_init_verbs },
8599 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8600 .dac_nids = alc883_dac_nids,
8601 .dig_out_nid = ALC883_DIGOUT_NID,
8602 .dig_in_nid = ALC883_DIGIN_NID,
8603 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8604 .channel_mode = alc883_3ST_6ch_modes,
8606 .input_mux = &alc883_capture_source,
8608 [ALC883_3ST_6ch] = {
8609 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8610 .init_verbs = { alc883_init_verbs },
8611 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8612 .dac_nids = alc883_dac_nids,
8613 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8614 .channel_mode = alc883_3ST_6ch_modes,
8616 .input_mux = &alc883_capture_source,
8618 [ALC883_3ST_6ch_INTEL] = {
8619 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8620 .init_verbs = { alc883_init_verbs },
8621 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8622 .dac_nids = alc883_dac_nids,
8623 .dig_out_nid = ALC883_DIGOUT_NID,
8624 .dig_in_nid = ALC883_DIGIN_NID,
8625 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8626 .channel_mode = alc883_3ST_6ch_intel_modes,
8628 .input_mux = &alc883_3stack_6ch_intel,
8630 [ALC883_6ST_DIG] = {
8631 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8632 .init_verbs = { alc883_init_verbs },
8633 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8634 .dac_nids = alc883_dac_nids,
8635 .dig_out_nid = ALC883_DIGOUT_NID,
8636 .dig_in_nid = ALC883_DIGIN_NID,
8637 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8638 .channel_mode = alc883_sixstack_modes,
8639 .input_mux = &alc883_capture_source,
8641 [ALC883_TARGA_DIG] = {
8642 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8643 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8644 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8645 .dac_nids = alc883_dac_nids,
8646 .dig_out_nid = ALC883_DIGOUT_NID,
8647 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8648 .channel_mode = alc883_3ST_6ch_modes,
8650 .input_mux = &alc883_capture_source,
8651 .unsol_event = alc883_tagra_unsol_event,
8652 .init_hook = alc883_tagra_automute,
8654 [ALC883_TARGA_2ch_DIG] = {
8655 .mixers = { alc883_tagra_2ch_mixer},
8656 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8657 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8658 .dac_nids = alc883_dac_nids,
8659 .adc_nids = alc883_adc_nids_alt,
8660 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8661 .dig_out_nid = ALC883_DIGOUT_NID,
8662 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8663 .channel_mode = alc883_3ST_2ch_modes,
8664 .input_mux = &alc883_capture_source,
8665 .unsol_event = alc883_tagra_unsol_event,
8666 .init_hook = alc883_tagra_automute,
8669 .mixers = { alc883_base_mixer },
8670 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8671 * and the headphone jack. Turn this on and rely on the
8672 * standard mute methods whenever the user wants to turn
8673 * these outputs off.
8675 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8676 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8677 .dac_nids = alc883_dac_nids,
8678 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8679 .channel_mode = alc883_3ST_2ch_modes,
8680 .input_mux = &alc883_capture_source,
8682 [ALC883_ACER_ASPIRE] = {
8683 .mixers = { alc883_acer_aspire_mixer },
8684 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8685 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8686 .dac_nids = alc883_dac_nids,
8687 .dig_out_nid = ALC883_DIGOUT_NID,
8688 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8689 .channel_mode = alc883_3ST_2ch_modes,
8690 .input_mux = &alc883_capture_source,
8691 .unsol_event = alc883_acer_aspire_unsol_event,
8692 .init_hook = alc883_acer_aspire_automute,
8694 [ALC888_ACER_ASPIRE_4930G] = {
8695 .mixers = { alc888_base_mixer,
8696 alc883_chmode_mixer },
8697 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8698 alc888_acer_aspire_4930g_verbs },
8699 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8700 .dac_nids = alc883_dac_nids,
8701 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8702 .adc_nids = alc883_adc_nids_rev,
8703 .capsrc_nids = alc883_capsrc_nids_rev,
8704 .dig_out_nid = ALC883_DIGOUT_NID,
8705 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8706 .channel_mode = alc883_3ST_6ch_modes,
8709 ARRAY_SIZE(alc888_2_capture_sources),
8710 .input_mux = alc888_2_capture_sources,
8711 .unsol_event = alc888_acer_aspire_4930g_unsol_event,
8712 .init_hook = alc888_acer_aspire_4930g_automute,
8715 .mixers = { alc883_fivestack_mixer,
8716 alc883_chmode_mixer },
8717 .init_verbs = { alc883_init_verbs,
8718 alc883_medion_eapd_verbs },
8719 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8720 .dac_nids = alc883_dac_nids,
8721 .adc_nids = alc883_adc_nids_alt,
8722 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8723 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8724 .channel_mode = alc883_sixstack_modes,
8725 .input_mux = &alc883_capture_source,
8727 [ALC883_MEDION_MD2] = {
8728 .mixers = { alc883_medion_md2_mixer},
8729 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8730 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8731 .dac_nids = alc883_dac_nids,
8732 .dig_out_nid = ALC883_DIGOUT_NID,
8733 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8734 .channel_mode = alc883_3ST_2ch_modes,
8735 .input_mux = &alc883_capture_source,
8736 .unsol_event = alc883_medion_md2_unsol_event,
8737 .init_hook = alc883_medion_md2_automute,
8739 [ALC883_LAPTOP_EAPD] = {
8740 .mixers = { alc883_base_mixer },
8741 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8742 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8743 .dac_nids = alc883_dac_nids,
8744 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8745 .channel_mode = alc883_3ST_2ch_modes,
8746 .input_mux = &alc883_capture_source,
8748 [ALC883_CLEVO_M720] = {
8749 .mixers = { alc883_clevo_m720_mixer },
8750 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8751 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8752 .dac_nids = alc883_dac_nids,
8753 .dig_out_nid = ALC883_DIGOUT_NID,
8754 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8755 .channel_mode = alc883_3ST_2ch_modes,
8756 .input_mux = &alc883_capture_source,
8757 .unsol_event = alc883_clevo_m720_unsol_event,
8758 .init_hook = alc883_clevo_m720_automute,
8760 [ALC883_LENOVO_101E_2ch] = {
8761 .mixers = { alc883_lenovo_101e_2ch_mixer},
8762 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8763 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8764 .dac_nids = alc883_dac_nids,
8765 .adc_nids = alc883_adc_nids_alt,
8766 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8767 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8768 .channel_mode = alc883_3ST_2ch_modes,
8769 .input_mux = &alc883_lenovo_101e_capture_source,
8770 .unsol_event = alc883_lenovo_101e_unsol_event,
8771 .init_hook = alc883_lenovo_101e_all_automute,
8773 [ALC883_LENOVO_NB0763] = {
8774 .mixers = { alc883_lenovo_nb0763_mixer },
8775 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8776 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8777 .dac_nids = alc883_dac_nids,
8778 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8779 .channel_mode = alc883_3ST_2ch_modes,
8781 .input_mux = &alc883_lenovo_nb0763_capture_source,
8782 .unsol_event = alc883_medion_md2_unsol_event,
8783 .init_hook = alc883_medion_md2_automute,
8785 [ALC888_LENOVO_MS7195_DIG] = {
8786 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8787 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8788 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8789 .dac_nids = alc883_dac_nids,
8790 .dig_out_nid = ALC883_DIGOUT_NID,
8791 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8792 .channel_mode = alc883_3ST_6ch_modes,
8794 .input_mux = &alc883_capture_source,
8795 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8796 .init_hook = alc888_lenovo_ms7195_front_automute,
8798 [ALC883_HAIER_W66] = {
8799 .mixers = { alc883_tagra_2ch_mixer},
8800 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8801 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8802 .dac_nids = alc883_dac_nids,
8803 .dig_out_nid = ALC883_DIGOUT_NID,
8804 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8805 .channel_mode = alc883_3ST_2ch_modes,
8806 .input_mux = &alc883_capture_source,
8807 .unsol_event = alc883_haier_w66_unsol_event,
8808 .init_hook = alc883_haier_w66_automute,
8811 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8812 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8813 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8814 .dac_nids = alc883_dac_nids,
8815 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8816 .channel_mode = alc888_3st_hp_modes,
8818 .input_mux = &alc883_capture_source,
8820 [ALC888_6ST_DELL] = {
8821 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8822 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8823 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8824 .dac_nids = alc883_dac_nids,
8825 .dig_out_nid = ALC883_DIGOUT_NID,
8826 .dig_in_nid = ALC883_DIGIN_NID,
8827 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8828 .channel_mode = alc883_sixstack_modes,
8829 .input_mux = &alc883_capture_source,
8830 .unsol_event = alc888_6st_dell_unsol_event,
8831 .init_hook = alc888_6st_dell_front_automute,
8834 .mixers = { alc883_mitac_mixer },
8835 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8836 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8837 .dac_nids = alc883_dac_nids,
8838 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8839 .channel_mode = alc883_3ST_2ch_modes,
8840 .input_mux = &alc883_capture_source,
8841 .unsol_event = alc883_mitac_unsol_event,
8842 .init_hook = alc883_mitac_automute,
8844 [ALC883_FUJITSU_PI2515] = {
8845 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8846 .init_verbs = { alc883_init_verbs,
8847 alc883_2ch_fujitsu_pi2515_verbs},
8848 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8849 .dac_nids = alc883_dac_nids,
8850 .dig_out_nid = ALC883_DIGOUT_NID,
8851 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8852 .channel_mode = alc883_3ST_2ch_modes,
8853 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8854 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8855 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8857 [ALC888_FUJITSU_XA3530] = {
8858 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
8859 .init_verbs = { alc883_init_verbs,
8860 alc888_fujitsu_xa3530_verbs },
8861 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8862 .dac_nids = alc883_dac_nids,
8863 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8864 .adc_nids = alc883_adc_nids_rev,
8865 .capsrc_nids = alc883_capsrc_nids_rev,
8866 .dig_out_nid = ALC883_DIGOUT_NID,
8867 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
8868 .channel_mode = alc888_4ST_8ch_intel_modes,
8870 ARRAY_SIZE(alc888_2_capture_sources),
8871 .input_mux = alc888_2_capture_sources,
8872 .unsol_event = alc888_fujitsu_xa3530_unsol_event,
8873 .init_hook = alc888_fujitsu_xa3530_automute,
8875 [ALC888_LENOVO_SKY] = {
8876 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8877 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8878 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8879 .dac_nids = alc883_dac_nids,
8880 .dig_out_nid = ALC883_DIGOUT_NID,
8881 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8882 .channel_mode = alc883_sixstack_modes,
8884 .input_mux = &alc883_lenovo_sky_capture_source,
8885 .unsol_event = alc883_lenovo_sky_unsol_event,
8886 .init_hook = alc888_lenovo_sky_front_automute,
8888 [ALC888_ASUS_M90V] = {
8889 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8890 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8891 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8892 .dac_nids = alc883_dac_nids,
8893 .dig_out_nid = ALC883_DIGOUT_NID,
8894 .dig_in_nid = ALC883_DIGIN_NID,
8895 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8896 .channel_mode = alc883_3ST_6ch_modes,
8898 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8899 .unsol_event = alc883_mode2_unsol_event,
8900 .init_hook = alc883_mode2_inithook,
8902 [ALC888_ASUS_EEE1601] = {
8903 .mixers = { alc883_asus_eee1601_mixer },
8904 .cap_mixer = alc883_asus_eee1601_cap_mixer,
8905 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8906 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8907 .dac_nids = alc883_dac_nids,
8908 .dig_out_nid = ALC883_DIGOUT_NID,
8909 .dig_in_nid = ALC883_DIGIN_NID,
8910 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8911 .channel_mode = alc883_3ST_2ch_modes,
8913 .input_mux = &alc883_asus_eee1601_capture_source,
8914 .unsol_event = alc883_eee1601_unsol_event,
8915 .init_hook = alc883_eee1601_inithook,
8917 [ALC1200_ASUS_P5Q] = {
8918 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8919 .init_verbs = { alc883_init_verbs },
8920 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8921 .dac_nids = alc883_dac_nids,
8922 .dig_out_nid = ALC1200_DIGOUT_NID,
8923 .dig_in_nid = ALC883_DIGIN_NID,
8924 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8925 .channel_mode = alc883_sixstack_modes,
8926 .input_mux = &alc883_capture_source,
8932 * BIOS auto configuration
8934 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8935 hda_nid_t nid, int pin_type,
8939 struct alc_spec *spec = codec->spec;
8942 alc_set_pin_output(codec, nid, pin_type);
8943 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8946 idx = spec->multiout.dac_nids[dac_idx] - 2;
8947 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8951 static void alc883_auto_init_multi_out(struct hda_codec *codec)
8953 struct alc_spec *spec = codec->spec;
8956 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8957 for (i = 0; i <= HDA_SIDE; i++) {
8958 hda_nid_t nid = spec->autocfg.line_out_pins[i];
8959 int pin_type = get_pin_type(spec->autocfg.line_out_type);
8961 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8966 static void alc883_auto_init_hp_out(struct hda_codec *codec)
8968 struct alc_spec *spec = codec->spec;
8971 pin = spec->autocfg.hp_pins[0];
8972 if (pin) /* connect to front */
8974 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8975 pin = spec->autocfg.speaker_pins[0];
8977 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8980 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8981 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8983 static void alc883_auto_init_analog_input(struct hda_codec *codec)
8985 struct alc_spec *spec = codec->spec;
8988 for (i = 0; i < AUTO_PIN_LAST; i++) {
8989 hda_nid_t nid = spec->autocfg.input_pins[i];
8990 if (alc883_is_input_pin(nid)) {
8991 snd_hda_codec_write(codec, nid, 0,
8992 AC_VERB_SET_PIN_WIDGET_CONTROL,
8993 (i <= AUTO_PIN_FRONT_MIC ?
8994 PIN_VREF80 : PIN_IN));
8995 if (nid != ALC883_PIN_CD_NID)
8996 snd_hda_codec_write(codec, nid, 0,
8997 AC_VERB_SET_AMP_GAIN_MUTE,
9003 #define alc883_auto_init_input_src alc882_auto_init_input_src
9005 /* almost identical with ALC880 parser... */
9006 static int alc883_parse_auto_config(struct hda_codec *codec)
9008 struct alc_spec *spec = codec->spec;
9009 int err = alc880_parse_auto_config(codec);
9010 struct auto_pin_cfg *cfg = &spec->autocfg;
9016 return 0; /* no config found */
9018 err = alc_auto_add_mic_boost(codec);
9022 /* hack - override the init verbs */
9023 spec->init_verbs[0] = alc883_auto_init_verbs;
9025 /* setup input_mux for ALC889 */
9026 if (codec->vendor_id == 0x10ec0889) {
9027 /* digital-mic input pin is excluded in alc880_auto_create..()
9028 * because it's under 0x18
9030 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9031 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9032 struct hda_input_mux *imux = &spec->private_imux[0];
9033 for (i = 1; i < 3; i++)
9034 memcpy(&spec->private_imux[i],
9035 &spec->private_imux[0],
9036 sizeof(spec->private_imux[0]));
9037 imux->items[imux->num_items].label = "Int DMic";
9038 imux->items[imux->num_items].index = 0x0b;
9040 spec->num_mux_defs = 3;
9041 spec->input_mux = spec->private_imux;
9045 return 1; /* config found */
9048 /* additional initialization for auto-configuration model */
9049 static void alc883_auto_init(struct hda_codec *codec)
9051 struct alc_spec *spec = codec->spec;
9052 alc883_auto_init_multi_out(codec);
9053 alc883_auto_init_hp_out(codec);
9054 alc883_auto_init_analog_input(codec);
9055 alc883_auto_init_input_src(codec);
9056 if (spec->unsol_event)
9057 alc_inithook(codec);
9060 static int patch_alc883(struct hda_codec *codec)
9062 struct alc_spec *spec;
9063 int err, board_config;
9065 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9071 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9073 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9076 if (board_config < 0) {
9077 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
9078 "trying auto-probe from BIOS...\n");
9079 board_config = ALC883_AUTO;
9082 if (board_config == ALC883_AUTO) {
9083 /* automatic parse from the BIOS config */
9084 err = alc883_parse_auto_config(codec);
9090 "hda_codec: Cannot set up configuration "
9091 "from BIOS. Using base mode...\n");
9092 board_config = ALC883_3ST_2ch_DIG;
9096 if (board_config != ALC883_AUTO)
9097 setup_preset(spec, &alc883_presets[board_config]);
9099 switch (codec->vendor_id) {
9101 if (codec->revision_id == 0x100101) {
9102 spec->stream_name_analog = "ALC1200 Analog";
9103 spec->stream_name_digital = "ALC1200 Digital";
9105 spec->stream_name_analog = "ALC888 Analog";
9106 spec->stream_name_digital = "ALC888 Digital";
9108 if (!spec->num_adc_nids) {
9109 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9110 spec->adc_nids = alc883_adc_nids;
9112 if (!spec->capsrc_nids)
9113 spec->capsrc_nids = alc883_capsrc_nids;
9114 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9117 spec->stream_name_analog = "ALC889 Analog";
9118 spec->stream_name_digital = "ALC889 Digital";
9119 if (!spec->num_adc_nids) {
9120 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9121 spec->adc_nids = alc889_adc_nids;
9123 if (!spec->capsrc_nids)
9124 spec->capsrc_nids = alc889_capsrc_nids;
9125 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9129 spec->stream_name_analog = "ALC883 Analog";
9130 spec->stream_name_digital = "ALC883 Digital";
9131 if (!spec->num_adc_nids) {
9132 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9133 spec->adc_nids = alc883_adc_nids;
9135 if (!spec->capsrc_nids)
9136 spec->capsrc_nids = alc883_capsrc_nids;
9137 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9141 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9142 spec->stream_analog_capture = &alc883_pcm_analog_capture;
9143 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9145 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9146 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9148 if (!spec->cap_mixer)
9149 set_capture_mixer(spec);
9151 spec->vmaster_nid = 0x0c;
9153 codec->patch_ops = alc_patch_ops;
9154 if (board_config == ALC883_AUTO)
9155 spec->init_hook = alc883_auto_init;
9157 #ifdef CONFIG_SND_HDA_POWER_SAVE
9158 if (!spec->loopback.amplist)
9159 spec->loopback.amplist = alc883_loopbacks;
9161 codec->proc_widget_hook = print_realtek_coef;
9170 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9171 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
9173 #define alc262_dac_nids alc260_dac_nids
9174 #define alc262_adc_nids alc882_adc_nids
9175 #define alc262_adc_nids_alt alc882_adc_nids_alt
9176 #define alc262_capsrc_nids alc882_capsrc_nids
9177 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9179 #define alc262_modes alc260_modes
9180 #define alc262_capture_source alc882_capture_source
9182 static hda_nid_t alc262_dmic_adc_nids[1] = {
9187 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9189 static struct snd_kcontrol_new alc262_base_mixer[] = {
9190 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9191 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9192 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9193 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9194 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9195 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9196 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9197 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9198 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9199 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9200 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9201 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9202 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9203 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9204 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9205 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9206 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9207 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9211 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9212 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9213 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9214 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9215 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9216 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9217 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9218 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9219 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9220 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9221 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9222 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9223 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9224 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9225 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9226 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
9227 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9231 /* update HP, line and mono-out pins according to the master switch */
9232 static void alc262_hp_master_update(struct hda_codec *codec)
9234 struct alc_spec *spec = codec->spec;
9235 int val = spec->master_sw;
9238 snd_hda_codec_write_cache(codec, 0x1b, 0,
9239 AC_VERB_SET_PIN_WIDGET_CONTROL,
9241 snd_hda_codec_write_cache(codec, 0x15, 0,
9242 AC_VERB_SET_PIN_WIDGET_CONTROL,
9244 /* mono (speaker) depending on the HP jack sense */
9245 val = val && !spec->jack_present;
9246 snd_hda_codec_write_cache(codec, 0x16, 0,
9247 AC_VERB_SET_PIN_WIDGET_CONTROL,
9251 static void alc262_hp_bpc_automute(struct hda_codec *codec)
9253 struct alc_spec *spec = codec->spec;
9254 unsigned int presence;
9255 presence = snd_hda_codec_read(codec, 0x1b, 0,
9256 AC_VERB_GET_PIN_SENSE, 0);
9257 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9258 alc262_hp_master_update(codec);
9261 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9263 if ((res >> 26) != ALC880_HP_EVENT)
9265 alc262_hp_bpc_automute(codec);
9268 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9270 struct alc_spec *spec = codec->spec;
9271 unsigned int presence;
9272 presence = snd_hda_codec_read(codec, 0x15, 0,
9273 AC_VERB_GET_PIN_SENSE, 0);
9274 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9275 alc262_hp_master_update(codec);
9278 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9281 if ((res >> 26) != ALC880_HP_EVENT)
9283 alc262_hp_wildwest_automute(codec);
9286 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
9287 struct snd_ctl_elem_value *ucontrol)
9289 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9290 struct alc_spec *spec = codec->spec;
9291 *ucontrol->value.integer.value = spec->master_sw;
9295 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9296 struct snd_ctl_elem_value *ucontrol)
9298 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9299 struct alc_spec *spec = codec->spec;
9300 int val = !!*ucontrol->value.integer.value;
9302 if (val == spec->master_sw)
9304 spec->master_sw = val;
9305 alc262_hp_master_update(codec);
9309 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9311 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9312 .name = "Master Playback Switch",
9313 .info = snd_ctl_boolean_mono_info,
9314 .get = alc262_hp_master_sw_get,
9315 .put = alc262_hp_master_sw_put,
9317 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9318 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9319 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9320 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9322 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9324 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9325 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9326 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9327 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9328 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9329 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9330 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9331 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9332 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9333 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9334 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9335 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9336 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9337 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9341 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9343 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9344 .name = "Master Playback Switch",
9345 .info = snd_ctl_boolean_mono_info,
9346 .get = alc262_hp_master_sw_get,
9347 .put = alc262_hp_master_sw_put,
9349 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9350 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9351 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9352 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9353 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9355 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9357 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9358 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9359 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9360 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9361 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9362 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9363 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9364 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9365 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9369 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9370 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9371 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9372 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9376 /* mute/unmute internal speaker according to the hp jack and mute state */
9377 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9379 struct alc_spec *spec = codec->spec;
9381 if (force || !spec->sense_updated) {
9382 unsigned int present;
9383 present = snd_hda_codec_read(codec, 0x15, 0,
9384 AC_VERB_GET_PIN_SENSE, 0);
9385 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9386 spec->sense_updated = 1;
9388 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9389 spec->jack_present ? HDA_AMP_MUTE : 0);
9392 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9395 if ((res >> 26) != ALC880_HP_EVENT)
9397 alc262_hp_t5735_automute(codec, 1);
9400 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9402 alc262_hp_t5735_automute(codec, 1);
9405 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9406 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9407 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9408 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9409 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9410 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9411 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9412 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9416 static struct hda_verb alc262_hp_t5735_verbs[] = {
9417 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9418 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9420 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9424 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9425 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9426 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9427 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9428 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9429 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9430 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9434 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9435 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9436 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9437 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9438 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9439 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9440 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9441 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9442 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9443 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9444 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9448 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9455 /* bind hp and internal speaker mute (with plug check) */
9456 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9457 struct snd_ctl_elem_value *ucontrol)
9459 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9460 long *valp = ucontrol->value.integer.value;
9463 /* change hp mute */
9464 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9466 valp[0] ? 0 : HDA_AMP_MUTE);
9467 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9469 valp[1] ? 0 : HDA_AMP_MUTE);
9471 /* change speaker according to HP jack state */
9472 struct alc_spec *spec = codec->spec;
9474 if (spec->jack_present)
9475 mute = HDA_AMP_MUTE;
9477 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9479 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9480 HDA_AMP_MUTE, mute);
9485 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9486 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9488 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9489 .name = "Master Playback Switch",
9490 .info = snd_hda_mixer_amp_switch_info,
9491 .get = snd_hda_mixer_amp_switch_get,
9492 .put = alc262_sony_master_sw_put,
9493 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9495 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9496 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9497 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9498 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9502 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9503 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9504 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9505 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9506 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9507 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9508 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9509 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9513 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9514 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9515 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9516 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9517 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9518 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9519 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9520 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9521 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9522 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9523 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9524 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9525 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9529 static struct hda_verb alc262_tyan_verbs[] = {
9530 /* Headphone automute */
9531 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9532 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9533 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9535 /* P11 AUX_IN, white 4-pin connector */
9536 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9537 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9538 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9539 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9544 /* unsolicited event for HP jack sensing */
9545 static void alc262_tyan_automute(struct hda_codec *codec)
9548 unsigned int present;
9550 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9551 present = snd_hda_codec_read(codec, 0x1b, 0,
9552 AC_VERB_GET_PIN_SENSE, 0);
9553 present = (present & 0x80000000) != 0;
9555 /* mute line output on ATX panel */
9556 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9557 HDA_AMP_MUTE, HDA_AMP_MUTE);
9559 /* unmute line output if necessary */
9560 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9561 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9562 HDA_AMP_MUTE, mute);
9566 static void alc262_tyan_unsol_event(struct hda_codec *codec,
9569 if ((res >> 26) != ALC880_HP_EVENT)
9571 alc262_tyan_automute(codec);
9574 #define alc262_capture_mixer alc882_capture_mixer
9575 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9578 * generic initialization of ADC, input mixers and output mixers
9580 static struct hda_verb alc262_init_verbs[] = {
9582 * Unmute ADC0-2 and set the default input to mic-in
9584 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9585 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9586 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9587 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9588 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9589 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9591 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9593 * Note: PASD motherboards uses the Line In 2 as the input for
9594 * front panel mic (mic 2)
9596 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9597 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9598 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9599 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9600 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9601 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9604 * Set up output mixers (0x0c - 0x0e)
9606 /* set vol=0 to output mixers */
9607 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9608 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9609 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9610 /* set up input amps for analog loopback */
9611 /* Amp Indices: DAC = 0, mixer = 1 */
9612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9614 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9616 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9617 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9619 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9620 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9621 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9622 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9623 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9624 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9626 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9627 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9628 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9629 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9630 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9632 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9633 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9635 /* FIXME: use matrix-type input source selection */
9636 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9637 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9638 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9639 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9640 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9641 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9643 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9644 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9645 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9646 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9648 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9649 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9650 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9651 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9656 static struct hda_verb alc262_eapd_verbs[] = {
9657 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9658 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9662 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9663 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9664 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9668 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9669 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9670 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9671 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9673 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9674 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9678 static struct hda_verb alc262_sony_unsol_verbs[] = {
9679 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9680 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9681 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9683 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9684 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9688 static struct hda_input_mux alc262_dmic_capture_source = {
9691 { "Int DMic", 0x9 },
9696 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9697 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9698 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9699 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9700 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9701 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9705 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9706 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9708 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9709 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9710 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9711 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9712 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9713 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9717 static void alc262_dmic_automute(struct hda_codec *codec)
9719 unsigned int present;
9721 present = snd_hda_codec_read(codec, 0x18, 0,
9722 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9723 snd_hda_codec_write(codec, 0x22, 0,
9724 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9727 /* toggle speaker-output according to the hp-jack state */
9728 static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9730 unsigned int present;
9733 present = snd_hda_codec_read(codec, 0x15, 0,
9734 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9735 bits = present ? 0 : PIN_OUT;
9736 snd_hda_codec_write(codec, 0x14, 0,
9737 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9742 /* unsolicited event for HP jack sensing */
9743 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9746 if ((res >> 26) == ALC880_HP_EVENT)
9747 alc262_toshiba_s06_speaker_automute(codec);
9748 if ((res >> 26) == ALC880_MIC_EVENT)
9749 alc262_dmic_automute(codec);
9753 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9755 alc262_toshiba_s06_speaker_automute(codec);
9756 alc262_dmic_automute(codec);
9759 /* mute/unmute internal speaker according to the hp jack and mute state */
9760 static void alc262_hippo_automute(struct hda_codec *codec)
9762 struct alc_spec *spec = codec->spec;
9764 unsigned int present;
9766 /* need to execute and sync at first */
9767 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9768 present = snd_hda_codec_read(codec, 0x15, 0,
9769 AC_VERB_GET_PIN_SENSE, 0);
9770 spec->jack_present = (present & 0x80000000) != 0;
9771 if (spec->jack_present) {
9772 /* mute internal speaker */
9773 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9774 HDA_AMP_MUTE, HDA_AMP_MUTE);
9776 /* unmute internal speaker if necessary */
9777 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9778 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9779 HDA_AMP_MUTE, mute);
9783 /* unsolicited event for HP jack sensing */
9784 static void alc262_hippo_unsol_event(struct hda_codec *codec,
9787 if ((res >> 26) != ALC880_HP_EVENT)
9789 alc262_hippo_automute(codec);
9792 static void alc262_hippo1_automute(struct hda_codec *codec)
9795 unsigned int present;
9797 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9798 present = snd_hda_codec_read(codec, 0x1b, 0,
9799 AC_VERB_GET_PIN_SENSE, 0);
9800 present = (present & 0x80000000) != 0;
9802 /* mute internal speaker */
9803 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9804 HDA_AMP_MUTE, HDA_AMP_MUTE);
9806 /* unmute internal speaker if necessary */
9807 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9808 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9809 HDA_AMP_MUTE, mute);
9813 /* unsolicited event for HP jack sensing */
9814 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9817 if ((res >> 26) != ALC880_HP_EVENT)
9819 alc262_hippo1_automute(codec);
9825 * 0x16 = internal speaker
9826 * 0x18 = external mic
9829 static struct snd_kcontrol_new alc262_nec_mixer[] = {
9830 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9831 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9835 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9837 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9838 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9842 static struct hda_verb alc262_nec_verbs[] = {
9843 /* Unmute Speaker */
9844 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9847 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9848 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9850 /* External mic to headphone */
9851 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9852 /* External mic to speaker */
9853 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9859 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9860 * 0x1b = port replicator headphone out
9863 #define ALC_HP_EVENT 0x37
9865 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9866 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9867 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9868 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9869 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9873 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9874 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9875 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9879 static struct hda_input_mux alc262_fujitsu_capture_source = {
9888 static struct hda_input_mux alc262_HP_capture_source = {
9892 { "Front Mic", 0x1 },
9899 static struct hda_input_mux alc262_HP_D7000_capture_source = {
9903 { "Front Mic", 0x2 },
9909 /* mute/unmute internal speaker according to the hp jacks and mute state */
9910 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9912 struct alc_spec *spec = codec->spec;
9915 if (force || !spec->sense_updated) {
9916 unsigned int present;
9917 /* need to execute and sync at first */
9918 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9919 /* check laptop HP jack */
9920 present = snd_hda_codec_read(codec, 0x14, 0,
9921 AC_VERB_GET_PIN_SENSE, 0);
9922 /* need to execute and sync at first */
9923 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9924 /* check docking HP jack */
9925 present |= snd_hda_codec_read(codec, 0x1b, 0,
9926 AC_VERB_GET_PIN_SENSE, 0);
9927 if (present & AC_PINSENSE_PRESENCE)
9928 spec->jack_present = 1;
9930 spec->jack_present = 0;
9931 spec->sense_updated = 1;
9933 /* unmute internal speaker only if both HPs are unplugged and
9934 * master switch is on
9936 if (spec->jack_present)
9937 mute = HDA_AMP_MUTE;
9939 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9940 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9941 HDA_AMP_MUTE, mute);
9944 /* unsolicited event for HP jack sensing */
9945 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9948 if ((res >> 26) != ALC_HP_EVENT)
9950 alc262_fujitsu_automute(codec, 1);
9953 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9955 alc262_fujitsu_automute(codec, 1);
9958 /* bind volumes of both NID 0x0c and 0x0d */
9959 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9960 .ops = &snd_hda_bind_vol,
9962 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9963 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9968 /* mute/unmute internal speaker according to the hp jack and mute state */
9969 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9971 struct alc_spec *spec = codec->spec;
9974 if (force || !spec->sense_updated) {
9975 unsigned int present_int_hp;
9976 /* need to execute and sync at first */
9977 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9978 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9979 AC_VERB_GET_PIN_SENSE, 0);
9980 spec->jack_present = (present_int_hp & 0x80000000) != 0;
9981 spec->sense_updated = 1;
9983 if (spec->jack_present) {
9984 /* mute internal speaker */
9985 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9986 HDA_AMP_MUTE, HDA_AMP_MUTE);
9987 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9988 HDA_AMP_MUTE, HDA_AMP_MUTE);
9990 /* unmute internal speaker if necessary */
9991 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9992 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9993 HDA_AMP_MUTE, mute);
9994 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9995 HDA_AMP_MUTE, mute);
9999 /* unsolicited event for HP jack sensing */
10000 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10003 if ((res >> 26) != ALC_HP_EVENT)
10005 alc262_lenovo_3000_automute(codec, 1);
10008 /* bind hp and internal speaker mute (with plug check) */
10009 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10010 struct snd_ctl_elem_value *ucontrol)
10012 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10013 long *valp = ucontrol->value.integer.value;
10016 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10018 valp ? 0 : HDA_AMP_MUTE);
10019 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10021 valp ? 0 : HDA_AMP_MUTE);
10024 alc262_fujitsu_automute(codec, 0);
10028 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10029 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10031 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10032 .name = "Master Playback Switch",
10033 .info = snd_hda_mixer_amp_switch_info,
10034 .get = snd_hda_mixer_amp_switch_get,
10035 .put = alc262_fujitsu_master_sw_put,
10036 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10038 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10039 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10040 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
10041 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
10042 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10043 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10044 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10045 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10046 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10047 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10051 /* bind hp and internal speaker mute (with plug check) */
10052 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10053 struct snd_ctl_elem_value *ucontrol)
10055 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10056 long *valp = ucontrol->value.integer.value;
10059 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10061 valp ? 0 : HDA_AMP_MUTE);
10064 alc262_lenovo_3000_automute(codec, 0);
10068 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10069 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10071 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10072 .name = "Master Playback Switch",
10073 .info = snd_hda_mixer_amp_switch_info,
10074 .get = snd_hda_mixer_amp_switch_get,
10075 .put = alc262_lenovo_3000_master_sw_put,
10076 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10078 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10079 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10080 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10081 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10082 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10083 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10084 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10085 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10089 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10090 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10092 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10093 .name = "Master Playback Switch",
10094 .info = snd_hda_mixer_amp_switch_info,
10095 .get = snd_hda_mixer_amp_switch_get,
10096 .put = alc262_sony_master_sw_put,
10097 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
10099 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10100 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10101 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10102 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10103 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10104 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10108 /* additional init verbs for Benq laptops */
10109 static struct hda_verb alc262_EAPD_verbs[] = {
10110 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10111 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10115 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10116 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10117 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10119 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10120 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10124 /* Samsung Q1 Ultra Vista model setup */
10125 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10126 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10127 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10129 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10130 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10131 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10135 static struct hda_verb alc262_ultra_verbs[] = {
10137 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10138 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10139 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10141 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10142 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10143 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10144 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10146 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10147 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10148 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10149 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10150 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10152 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10153 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10154 /* ADC, choose mic */
10155 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10156 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10157 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10158 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10159 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10160 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10161 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10162 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10163 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10164 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10168 /* mute/unmute internal speaker according to the hp jack and mute state */
10169 static void alc262_ultra_automute(struct hda_codec *codec)
10171 struct alc_spec *spec = codec->spec;
10175 /* auto-mute only when HP is used as HP */
10176 if (!spec->cur_mux[0]) {
10177 unsigned int present;
10178 /* need to execute and sync at first */
10179 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10180 present = snd_hda_codec_read(codec, 0x15, 0,
10181 AC_VERB_GET_PIN_SENSE, 0);
10182 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10183 if (spec->jack_present)
10184 mute = HDA_AMP_MUTE;
10186 /* mute/unmute internal speaker */
10187 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10188 HDA_AMP_MUTE, mute);
10189 /* mute/unmute HP */
10190 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10191 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10194 /* unsolicited event for HP jack sensing */
10195 static void alc262_ultra_unsol_event(struct hda_codec *codec,
10198 if ((res >> 26) != ALC880_HP_EVENT)
10200 alc262_ultra_automute(codec);
10203 static struct hda_input_mux alc262_ultra_capture_source = {
10207 { "Headphone", 0x7 },
10211 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10212 struct snd_ctl_elem_value *ucontrol)
10214 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10215 struct alc_spec *spec = codec->spec;
10218 ret = alc_mux_enum_put(kcontrol, ucontrol);
10221 /* reprogram the HP pin as mic or HP according to the input source */
10222 snd_hda_codec_write_cache(codec, 0x15, 0,
10223 AC_VERB_SET_PIN_WIDGET_CONTROL,
10224 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10225 alc262_ultra_automute(codec); /* mute/unmute HP */
10229 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10230 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10231 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10233 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10234 .name = "Capture Source",
10235 .info = alc_mux_enum_info,
10236 .get = alc_mux_enum_get,
10237 .put = alc262_ultra_mux_enum_put,
10242 /* add playback controls from the parsed DAC table */
10243 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10244 const struct auto_pin_cfg *cfg)
10249 spec->multiout.num_dacs = 1; /* only use one dac */
10250 spec->multiout.dac_nids = spec->private_dac_nids;
10251 spec->multiout.dac_nids[0] = 2;
10253 nid = cfg->line_out_pins[0];
10255 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10256 "Front Playback Volume",
10257 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10260 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10261 "Front Playback Switch",
10262 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10267 nid = cfg->speaker_pins[0];
10270 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10271 "Speaker Playback Volume",
10272 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10276 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10277 "Speaker Playback Switch",
10278 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10283 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10284 "Speaker Playback Switch",
10285 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10291 nid = cfg->hp_pins[0];
10293 /* spec->multiout.hp_nid = 2; */
10295 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10296 "Headphone Playback Volume",
10297 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10301 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10302 "Headphone Playback Switch",
10303 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10308 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10309 "Headphone Playback Switch",
10310 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10319 /* identical with ALC880 */
10320 #define alc262_auto_create_analog_input_ctls \
10321 alc880_auto_create_analog_input_ctls
10324 * generic initialization of ADC, input mixers and output mixers
10326 static struct hda_verb alc262_volume_init_verbs[] = {
10328 * Unmute ADC0-2 and set the default input to mic-in
10330 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10331 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10332 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10333 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10334 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10335 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10337 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10339 * Note: PASD motherboards uses the Line In 2 as the input for
10340 * front panel mic (mic 2)
10342 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10343 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10344 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10345 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10346 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10347 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10350 * Set up output mixers (0x0c - 0x0f)
10352 /* set vol=0 to output mixers */
10353 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10354 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10355 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10357 /* set up input amps for analog loopback */
10358 /* Amp Indices: DAC = 0, mixer = 1 */
10359 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10361 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10362 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10363 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10364 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10366 /* FIXME: use matrix-type input source selection */
10367 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10368 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10369 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10370 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10371 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10372 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10374 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10375 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10376 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10377 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10379 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10380 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10381 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10382 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10387 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10389 * Unmute ADC0-2 and set the default input to mic-in
10391 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10392 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10393 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10394 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10395 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10396 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10398 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10400 * Note: PASD motherboards uses the Line In 2 as the input for
10401 * front panel mic (mic 2)
10403 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10405 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10406 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10407 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10408 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10409 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10410 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10413 * Set up output mixers (0x0c - 0x0e)
10415 /* set vol=0 to output mixers */
10416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10420 /* set up input amps for analog loopback */
10421 /* Amp Indices: DAC = 0, mixer = 1 */
10422 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10423 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10424 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10425 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10426 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10427 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10429 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10430 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10431 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10433 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10434 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10436 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10437 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10439 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10440 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10441 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10442 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10443 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10445 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10446 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10447 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10448 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10449 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10450 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10453 /* FIXME: use matrix-type input source selection */
10454 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10455 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10456 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10457 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10458 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10459 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10461 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10462 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10466 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10467 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10468 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10469 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10471 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10476 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10478 * Unmute ADC0-2 and set the default input to mic-in
10480 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10481 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10482 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10483 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10484 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10485 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10487 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10489 * Note: PASD motherboards uses the Line In 2 as the input for front
10490 * panel mic (mic 2)
10492 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10493 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10494 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10495 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10496 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10497 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10498 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10499 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10500 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10502 * Set up output mixers (0x0c - 0x0e)
10504 /* set vol=0 to output mixers */
10505 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10509 /* set up input amps for analog loopback */
10510 /* Amp Indices: DAC = 0, mixer = 1 */
10511 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10515 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10519 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10520 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10521 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10522 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10523 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10524 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10525 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10527 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10528 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10530 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10531 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10533 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10534 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10535 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10536 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10537 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10538 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10540 /* FIXME: use matrix-type input source selection */
10541 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10542 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10543 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10544 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10545 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10546 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10547 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10548 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10549 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10551 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10552 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10553 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10554 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10555 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10556 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10557 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10559 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10560 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10561 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10562 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10563 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10564 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10565 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10567 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10572 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10574 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10575 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10576 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10578 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10579 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10580 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10581 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10583 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10584 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10585 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10590 #ifdef CONFIG_SND_HDA_POWER_SAVE
10591 #define alc262_loopbacks alc880_loopbacks
10594 /* pcm configuration: identiacal with ALC880 */
10595 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10596 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10597 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10598 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10601 * BIOS auto configuration
10603 static int alc262_parse_auto_config(struct hda_codec *codec)
10605 struct alc_spec *spec = codec->spec;
10607 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10609 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10613 if (!spec->autocfg.line_outs) {
10614 if (spec->autocfg.dig_out_pin || spec->autocfg.dig_in_pin) {
10615 spec->multiout.max_channels = 2;
10616 spec->no_analog = 1;
10619 return 0; /* can't find valid BIOS pin config */
10621 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10624 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10628 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10631 if (spec->autocfg.dig_out_pin) {
10632 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10633 spec->dig_out_type = spec->autocfg.dig_out_type;
10635 if (spec->autocfg.dig_in_pin)
10636 spec->dig_in_nid = ALC262_DIGIN_NID;
10638 if (spec->kctls.list)
10639 add_mixer(spec, spec->kctls.list);
10641 add_verb(spec, alc262_volume_init_verbs);
10642 spec->num_mux_defs = 1;
10643 spec->input_mux = &spec->private_imux[0];
10645 err = alc_auto_add_mic_boost(codec);
10649 store_pin_configs(codec);
10653 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10654 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10655 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10656 #define alc262_auto_init_input_src alc882_auto_init_input_src
10659 /* init callback for auto-configuration model -- overriding the default init */
10660 static void alc262_auto_init(struct hda_codec *codec)
10662 struct alc_spec *spec = codec->spec;
10663 alc262_auto_init_multi_out(codec);
10664 alc262_auto_init_hp_out(codec);
10665 alc262_auto_init_analog_input(codec);
10666 alc262_auto_init_input_src(codec);
10667 if (spec->unsol_event)
10668 alc_inithook(codec);
10672 * configuration and preset
10674 static const char *alc262_models[ALC262_MODEL_LAST] = {
10675 [ALC262_BASIC] = "basic",
10676 [ALC262_HIPPO] = "hippo",
10677 [ALC262_HIPPO_1] = "hippo_1",
10678 [ALC262_FUJITSU] = "fujitsu",
10679 [ALC262_HP_BPC] = "hp-bpc",
10680 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10681 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10682 [ALC262_HP_RP5700] = "hp-rp5700",
10683 [ALC262_BENQ_ED8] = "benq",
10684 [ALC262_BENQ_T31] = "benq-t31",
10685 [ALC262_SONY_ASSAMD] = "sony-assamd",
10686 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10687 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10688 [ALC262_ULTRA] = "ultra",
10689 [ALC262_LENOVO_3000] = "lenovo-3000",
10690 [ALC262_NEC] = "nec",
10691 [ALC262_TYAN] = "tyan",
10692 [ALC262_AUTO] = "auto",
10695 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10696 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10697 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10698 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10699 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10700 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10701 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10702 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10703 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10704 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10705 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10706 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10707 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10708 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10709 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10710 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10711 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10712 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10713 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10714 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10715 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10716 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10717 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10718 ALC262_HP_TC_T5735),
10719 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10720 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10721 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10722 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10723 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10724 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10725 SND_PCI_QUIRK(0x104d, 0x9033, "Sony VAIO VGN-SR19XN",
10726 ALC262_SONY_ASSAMD),
10727 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10728 ALC262_TOSHIBA_RX1),
10729 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10730 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10731 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10732 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
10733 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10734 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10735 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
10736 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10737 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10738 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10739 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10743 static struct alc_config_preset alc262_presets[] = {
10745 .mixers = { alc262_base_mixer },
10746 .init_verbs = { alc262_init_verbs },
10747 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10748 .dac_nids = alc262_dac_nids,
10750 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10751 .channel_mode = alc262_modes,
10752 .input_mux = &alc262_capture_source,
10755 .mixers = { alc262_base_mixer },
10756 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10757 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10758 .dac_nids = alc262_dac_nids,
10760 .dig_out_nid = ALC262_DIGOUT_NID,
10761 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10762 .channel_mode = alc262_modes,
10763 .input_mux = &alc262_capture_source,
10764 .unsol_event = alc262_hippo_unsol_event,
10765 .init_hook = alc262_hippo_automute,
10767 [ALC262_HIPPO_1] = {
10768 .mixers = { alc262_hippo1_mixer },
10769 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10770 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10771 .dac_nids = alc262_dac_nids,
10773 .dig_out_nid = ALC262_DIGOUT_NID,
10774 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10775 .channel_mode = alc262_modes,
10776 .input_mux = &alc262_capture_source,
10777 .unsol_event = alc262_hippo1_unsol_event,
10778 .init_hook = alc262_hippo1_automute,
10780 [ALC262_FUJITSU] = {
10781 .mixers = { alc262_fujitsu_mixer },
10782 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10783 alc262_fujitsu_unsol_verbs },
10784 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10785 .dac_nids = alc262_dac_nids,
10787 .dig_out_nid = ALC262_DIGOUT_NID,
10788 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10789 .channel_mode = alc262_modes,
10790 .input_mux = &alc262_fujitsu_capture_source,
10791 .unsol_event = alc262_fujitsu_unsol_event,
10792 .init_hook = alc262_fujitsu_init_hook,
10794 [ALC262_HP_BPC] = {
10795 .mixers = { alc262_HP_BPC_mixer },
10796 .init_verbs = { alc262_HP_BPC_init_verbs },
10797 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10798 .dac_nids = alc262_dac_nids,
10800 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10801 .channel_mode = alc262_modes,
10802 .input_mux = &alc262_HP_capture_source,
10803 .unsol_event = alc262_hp_bpc_unsol_event,
10804 .init_hook = alc262_hp_bpc_automute,
10806 [ALC262_HP_BPC_D7000_WF] = {
10807 .mixers = { alc262_HP_BPC_WildWest_mixer },
10808 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10809 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10810 .dac_nids = alc262_dac_nids,
10812 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10813 .channel_mode = alc262_modes,
10814 .input_mux = &alc262_HP_D7000_capture_source,
10815 .unsol_event = alc262_hp_wildwest_unsol_event,
10816 .init_hook = alc262_hp_wildwest_automute,
10818 [ALC262_HP_BPC_D7000_WL] = {
10819 .mixers = { alc262_HP_BPC_WildWest_mixer,
10820 alc262_HP_BPC_WildWest_option_mixer },
10821 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10822 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10823 .dac_nids = alc262_dac_nids,
10825 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10826 .channel_mode = alc262_modes,
10827 .input_mux = &alc262_HP_D7000_capture_source,
10828 .unsol_event = alc262_hp_wildwest_unsol_event,
10829 .init_hook = alc262_hp_wildwest_automute,
10831 [ALC262_HP_TC_T5735] = {
10832 .mixers = { alc262_hp_t5735_mixer },
10833 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10834 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10835 .dac_nids = alc262_dac_nids,
10837 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10838 .channel_mode = alc262_modes,
10839 .input_mux = &alc262_capture_source,
10840 .unsol_event = alc262_hp_t5735_unsol_event,
10841 .init_hook = alc262_hp_t5735_init_hook,
10843 [ALC262_HP_RP5700] = {
10844 .mixers = { alc262_hp_rp5700_mixer },
10845 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10846 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10847 .dac_nids = alc262_dac_nids,
10848 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10849 .channel_mode = alc262_modes,
10850 .input_mux = &alc262_hp_rp5700_capture_source,
10852 [ALC262_BENQ_ED8] = {
10853 .mixers = { alc262_base_mixer },
10854 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10855 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10856 .dac_nids = alc262_dac_nids,
10858 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10859 .channel_mode = alc262_modes,
10860 .input_mux = &alc262_capture_source,
10862 [ALC262_SONY_ASSAMD] = {
10863 .mixers = { alc262_sony_mixer },
10864 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10865 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10866 .dac_nids = alc262_dac_nids,
10868 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10869 .channel_mode = alc262_modes,
10870 .input_mux = &alc262_capture_source,
10871 .unsol_event = alc262_hippo_unsol_event,
10872 .init_hook = alc262_hippo_automute,
10874 [ALC262_BENQ_T31] = {
10875 .mixers = { alc262_benq_t31_mixer },
10876 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10877 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10878 .dac_nids = alc262_dac_nids,
10880 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10881 .channel_mode = alc262_modes,
10882 .input_mux = &alc262_capture_source,
10883 .unsol_event = alc262_hippo_unsol_event,
10884 .init_hook = alc262_hippo_automute,
10887 .mixers = { alc262_ultra_mixer },
10888 .cap_mixer = alc262_ultra_capture_mixer,
10889 .init_verbs = { alc262_ultra_verbs },
10890 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10891 .dac_nids = alc262_dac_nids,
10892 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10893 .channel_mode = alc262_modes,
10894 .input_mux = &alc262_ultra_capture_source,
10895 .adc_nids = alc262_adc_nids, /* ADC0 */
10896 .capsrc_nids = alc262_capsrc_nids,
10897 .num_adc_nids = 1, /* single ADC */
10898 .unsol_event = alc262_ultra_unsol_event,
10899 .init_hook = alc262_ultra_automute,
10901 [ALC262_LENOVO_3000] = {
10902 .mixers = { alc262_lenovo_3000_mixer },
10903 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10904 alc262_lenovo_3000_unsol_verbs },
10905 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10906 .dac_nids = alc262_dac_nids,
10908 .dig_out_nid = ALC262_DIGOUT_NID,
10909 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10910 .channel_mode = alc262_modes,
10911 .input_mux = &alc262_fujitsu_capture_source,
10912 .unsol_event = alc262_lenovo_3000_unsol_event,
10915 .mixers = { alc262_nec_mixer },
10916 .init_verbs = { alc262_nec_verbs },
10917 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10918 .dac_nids = alc262_dac_nids,
10920 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10921 .channel_mode = alc262_modes,
10922 .input_mux = &alc262_capture_source,
10924 [ALC262_TOSHIBA_S06] = {
10925 .mixers = { alc262_toshiba_s06_mixer },
10926 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10927 alc262_eapd_verbs },
10928 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10929 .capsrc_nids = alc262_dmic_capsrc_nids,
10930 .dac_nids = alc262_dac_nids,
10931 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10932 .dig_out_nid = ALC262_DIGOUT_NID,
10933 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10934 .channel_mode = alc262_modes,
10935 .input_mux = &alc262_dmic_capture_source,
10936 .unsol_event = alc262_toshiba_s06_unsol_event,
10937 .init_hook = alc262_toshiba_s06_init_hook,
10939 [ALC262_TOSHIBA_RX1] = {
10940 .mixers = { alc262_toshiba_rx1_mixer },
10941 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10942 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10943 .dac_nids = alc262_dac_nids,
10945 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10946 .channel_mode = alc262_modes,
10947 .input_mux = &alc262_capture_source,
10948 .unsol_event = alc262_hippo_unsol_event,
10949 .init_hook = alc262_hippo_automute,
10952 .mixers = { alc262_tyan_mixer },
10953 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
10954 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10955 .dac_nids = alc262_dac_nids,
10957 .dig_out_nid = ALC262_DIGOUT_NID,
10958 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10959 .channel_mode = alc262_modes,
10960 .input_mux = &alc262_capture_source,
10961 .unsol_event = alc262_tyan_unsol_event,
10962 .init_hook = alc262_tyan_automute,
10966 static int patch_alc262(struct hda_codec *codec)
10968 struct alc_spec *spec;
10972 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10976 codec->spec = spec;
10978 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
10983 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10984 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10985 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10986 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10990 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10992 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10996 if (board_config < 0) {
10997 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10998 "trying auto-probe from BIOS...\n");
10999 board_config = ALC262_AUTO;
11002 if (board_config == ALC262_AUTO) {
11003 /* automatic parse from the BIOS config */
11004 err = alc262_parse_auto_config(codec);
11010 "hda_codec: Cannot set up configuration "
11011 "from BIOS. Using base mode...\n");
11012 board_config = ALC262_BASIC;
11016 if (board_config != ALC262_AUTO)
11017 setup_preset(spec, &alc262_presets[board_config]);
11019 spec->stream_name_analog = "ALC262 Analog";
11020 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11021 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11023 spec->stream_name_digital = "ALC262 Digital";
11024 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11025 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11027 spec->capture_style = CAPT_MIX;
11028 if (!spec->adc_nids && spec->input_mux) {
11029 /* check whether NID 0x07 is valid */
11030 unsigned int wcap = get_wcaps(codec, 0x07);
11033 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11034 if (wcap != AC_WID_AUD_IN) {
11035 spec->adc_nids = alc262_adc_nids_alt;
11036 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
11037 spec->capsrc_nids = alc262_capsrc_nids_alt;
11039 spec->adc_nids = alc262_adc_nids;
11040 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
11041 spec->capsrc_nids = alc262_capsrc_nids;
11044 if (!spec->cap_mixer && !spec->no_analog)
11045 set_capture_mixer(spec);
11047 spec->vmaster_nid = 0x0c;
11049 codec->patch_ops = alc_patch_ops;
11050 if (board_config == ALC262_AUTO)
11051 spec->init_hook = alc262_auto_init;
11052 #ifdef CONFIG_SND_HDA_POWER_SAVE
11053 if (!spec->loopback.amplist)
11054 spec->loopback.amplist = alc262_loopbacks;
11056 codec->proc_widget_hook = print_realtek_coef;
11062 * ALC268 channel source setting (2 channel)
11064 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11065 #define alc268_modes alc260_modes
11067 static hda_nid_t alc268_dac_nids[2] = {
11072 static hda_nid_t alc268_adc_nids[2] = {
11077 static hda_nid_t alc268_adc_nids_alt[1] = {
11082 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11084 static struct snd_kcontrol_new alc268_base_mixer[] = {
11085 /* output mixer control */
11086 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11087 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11088 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11089 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11090 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11091 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11092 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11096 /* bind Beep switches of both NID 0x0f and 0x10 */
11097 static struct hda_bind_ctls alc268_bind_beep_sw = {
11098 .ops = &snd_hda_bind_sw,
11100 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11101 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11106 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11107 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11108 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11112 static struct hda_verb alc268_eapd_verbs[] = {
11113 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11114 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11118 /* Toshiba specific */
11119 #define alc268_toshiba_automute alc262_hippo_automute
11121 static struct hda_verb alc268_toshiba_verbs[] = {
11122 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11126 static struct hda_input_mux alc268_acer_lc_capture_source = {
11134 /* Acer specific */
11135 /* bind volumes of both NID 0x02 and 0x03 */
11136 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11137 .ops = &snd_hda_bind_vol,
11139 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11140 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11145 /* mute/unmute internal speaker according to the hp jack and mute state */
11146 static void alc268_acer_automute(struct hda_codec *codec, int force)
11148 struct alc_spec *spec = codec->spec;
11151 if (force || !spec->sense_updated) {
11152 unsigned int present;
11153 present = snd_hda_codec_read(codec, 0x14, 0,
11154 AC_VERB_GET_PIN_SENSE, 0);
11155 spec->jack_present = (present & 0x80000000) != 0;
11156 spec->sense_updated = 1;
11158 if (spec->jack_present)
11159 mute = HDA_AMP_MUTE; /* mute internal speaker */
11160 else /* unmute internal speaker if necessary */
11161 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11162 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11163 HDA_AMP_MUTE, mute);
11167 /* bind hp and internal speaker mute (with plug check) */
11168 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11169 struct snd_ctl_elem_value *ucontrol)
11171 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11172 long *valp = ucontrol->value.integer.value;
11175 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11177 valp[0] ? 0 : HDA_AMP_MUTE);
11178 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11180 valp[1] ? 0 : HDA_AMP_MUTE);
11182 alc268_acer_automute(codec, 0);
11186 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11187 /* output mixer control */
11188 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11190 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11191 .name = "Master Playback Switch",
11192 .info = snd_hda_mixer_amp_switch_info,
11193 .get = snd_hda_mixer_amp_switch_get,
11194 .put = alc268_acer_master_sw_put,
11195 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11197 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11201 static struct snd_kcontrol_new alc268_acer_mixer[] = {
11202 /* output mixer control */
11203 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11206 .name = "Master Playback Switch",
11207 .info = snd_hda_mixer_amp_switch_info,
11208 .get = snd_hda_mixer_amp_switch_get,
11209 .put = alc268_acer_master_sw_put,
11210 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11212 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11213 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11214 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11218 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11219 /* output mixer control */
11220 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11222 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11223 .name = "Master Playback Switch",
11224 .info = snd_hda_mixer_amp_switch_info,
11225 .get = snd_hda_mixer_amp_switch_get,
11226 .put = alc268_acer_master_sw_put,
11227 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11229 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11230 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11234 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11235 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11236 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11237 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11238 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11239 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11240 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11244 static struct hda_verb alc268_acer_verbs[] = {
11245 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11246 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11247 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11248 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11249 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11250 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11251 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11255 /* unsolicited event for HP jack sensing */
11256 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
11259 if ((res >> 26) != ALC880_HP_EVENT)
11261 alc268_toshiba_automute(codec);
11264 static void alc268_acer_unsol_event(struct hda_codec *codec,
11267 if ((res >> 26) != ALC880_HP_EVENT)
11269 alc268_acer_automute(codec, 1);
11272 static void alc268_acer_init_hook(struct hda_codec *codec)
11274 alc268_acer_automute(codec, 1);
11277 /* toggle speaker-output according to the hp-jack state */
11278 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11280 unsigned int present;
11281 unsigned char bits;
11283 present = snd_hda_codec_read(codec, 0x15, 0,
11284 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11285 bits = present ? AMP_IN_MUTE(0) : 0;
11286 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11287 AMP_IN_MUTE(0), bits);
11288 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11289 AMP_IN_MUTE(0), bits);
11293 static void alc268_acer_mic_automute(struct hda_codec *codec)
11295 unsigned int present;
11297 present = snd_hda_codec_read(codec, 0x18, 0,
11298 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11299 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11300 present ? 0x0 : 0x6);
11303 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11306 if ((res >> 26) == ALC880_HP_EVENT)
11307 alc268_aspire_one_speaker_automute(codec);
11308 if ((res >> 26) == ALC880_MIC_EVENT)
11309 alc268_acer_mic_automute(codec);
11312 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11314 alc268_aspire_one_speaker_automute(codec);
11315 alc268_acer_mic_automute(codec);
11318 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11319 /* output mixer control */
11320 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11321 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11322 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11323 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11324 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11325 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11329 static struct hda_verb alc268_dell_verbs[] = {
11330 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11331 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11332 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11336 /* mute/unmute internal speaker according to the hp jack and mute state */
11337 static void alc268_dell_automute(struct hda_codec *codec)
11339 unsigned int present;
11342 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
11343 if (present & 0x80000000)
11344 mute = HDA_AMP_MUTE;
11346 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
11347 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11348 HDA_AMP_MUTE, mute);
11351 static void alc268_dell_unsol_event(struct hda_codec *codec,
11354 if ((res >> 26) != ALC880_HP_EVENT)
11356 alc268_dell_automute(codec);
11359 #define alc268_dell_init_hook alc268_dell_automute
11361 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11362 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11363 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11364 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11366 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11367 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11368 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11369 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11373 static struct hda_verb alc267_quanta_il1_verbs[] = {
11374 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11375 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11379 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11381 unsigned int present;
11383 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11384 & AC_PINSENSE_PRESENCE;
11385 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11386 present ? 0 : PIN_OUT);
11389 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11391 unsigned int present;
11393 present = snd_hda_codec_read(codec, 0x18, 0,
11394 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11395 snd_hda_codec_write(codec, 0x23, 0,
11396 AC_VERB_SET_CONNECT_SEL,
11397 present ? 0x00 : 0x01);
11400 static void alc267_quanta_il1_automute(struct hda_codec *codec)
11402 alc267_quanta_il1_hp_automute(codec);
11403 alc267_quanta_il1_mic_automute(codec);
11406 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11409 switch (res >> 26) {
11410 case ALC880_HP_EVENT:
11411 alc267_quanta_il1_hp_automute(codec);
11413 case ALC880_MIC_EVENT:
11414 alc267_quanta_il1_mic_automute(codec);
11420 * generic initialization of ADC, input mixers and output mixers
11422 static struct hda_verb alc268_base_init_verbs[] = {
11423 /* Unmute DAC0-1 and set vol = 0 */
11424 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11425 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11428 * Set up output mixers (0x0c - 0x0e)
11430 /* set vol=0 to output mixers */
11431 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11432 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11434 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11435 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11437 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11438 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11439 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11440 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11441 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11442 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11443 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11444 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11446 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11448 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11449 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11450 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11452 /* set PCBEEP vol = 0, mute connections */
11453 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11454 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11455 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11457 /* Unmute Selector 23h,24h and set the default input to mic-in */
11459 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11460 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11461 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11462 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11468 * generic initialization of ADC, input mixers and output mixers
11470 static struct hda_verb alc268_volume_init_verbs[] = {
11471 /* set output DAC */
11472 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11473 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11475 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11476 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11477 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11478 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11479 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11481 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11482 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11483 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11485 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11486 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11488 /* set PCBEEP vol = 0, mute connections */
11489 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11490 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11491 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11496 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11497 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11498 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11500 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11501 /* The multiple "Capture Source" controls confuse alsamixer
11502 * So call somewhat different..
11504 /* .name = "Capture Source", */
11505 .name = "Input Source",
11507 .info = alc_mux_enum_info,
11508 .get = alc_mux_enum_get,
11509 .put = alc_mux_enum_put,
11514 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11515 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11516 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11517 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11518 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11520 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11521 /* The multiple "Capture Source" controls confuse alsamixer
11522 * So call somewhat different..
11524 /* .name = "Capture Source", */
11525 .name = "Input Source",
11527 .info = alc_mux_enum_info,
11528 .get = alc_mux_enum_get,
11529 .put = alc_mux_enum_put,
11534 static struct hda_input_mux alc268_capture_source = {
11538 { "Front Mic", 0x1 },
11544 static struct hda_input_mux alc268_acer_capture_source = {
11548 { "Internal Mic", 0x1 },
11553 static struct hda_input_mux alc268_acer_dmic_capture_source = {
11557 { "Internal Mic", 0x6 },
11562 #ifdef CONFIG_SND_DEBUG
11563 static struct snd_kcontrol_new alc268_test_mixer[] = {
11564 /* Volume widgets */
11565 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11566 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11567 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11568 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11569 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11570 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11571 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11572 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11573 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11574 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11575 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11576 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11577 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11578 /* The below appears problematic on some hardwares */
11579 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11580 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11581 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11582 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11583 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11585 /* Modes for retasking pin widgets */
11586 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11587 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11588 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11589 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11591 /* Controls for GPIO pins, assuming they are configured as outputs */
11592 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11593 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11594 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11595 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11597 /* Switches to allow the digital SPDIF output pin to be enabled.
11598 * The ALC268 does not have an SPDIF input.
11600 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11602 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11603 * this output to turn on an external amplifier.
11605 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11606 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11612 /* create input playback/capture controls for the given pin */
11613 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11614 const char *ctlname, int idx)
11619 sprintf(name, "%s Playback Volume", ctlname);
11621 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11622 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11626 } else if (nid == 0x15) {
11627 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11628 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11634 sprintf(name, "%s Playback Switch", ctlname);
11635 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11636 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11642 /* add playback controls from the parsed DAC table */
11643 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11644 const struct auto_pin_cfg *cfg)
11649 spec->multiout.num_dacs = 2; /* only use one dac */
11650 spec->multiout.dac_nids = spec->private_dac_nids;
11651 spec->multiout.dac_nids[0] = 2;
11652 spec->multiout.dac_nids[1] = 3;
11654 nid = cfg->line_out_pins[0];
11656 alc268_new_analog_output(spec, nid, "Front", 0);
11658 nid = cfg->speaker_pins[0];
11660 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11661 "Speaker Playback Volume",
11662 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11666 nid = cfg->hp_pins[0];
11668 alc268_new_analog_output(spec, nid, "Headphone", 0);
11670 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11672 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11673 "Mono Playback Switch",
11674 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11681 /* create playback/capture controls for input pins */
11682 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11683 const struct auto_pin_cfg *cfg)
11685 struct hda_input_mux *imux = &spec->private_imux[0];
11688 for (i = 0; i < AUTO_PIN_LAST; i++) {
11689 switch(cfg->input_pins[i]) {
11691 idx1 = 0; /* Mic 1 */
11694 idx1 = 1; /* Mic 2 */
11697 idx1 = 2; /* Line In */
11704 idx1 = 6; /* digital mics */
11709 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11710 imux->items[imux->num_items].index = idx1;
11716 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11718 struct alc_spec *spec = codec->spec;
11719 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11720 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11721 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11722 unsigned int dac_vol1, dac_vol2;
11725 snd_hda_codec_write(codec, speaker_nid, 0,
11726 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11727 snd_hda_codec_write(codec, 0x0f, 0,
11728 AC_VERB_SET_AMP_GAIN_MUTE,
11730 snd_hda_codec_write(codec, 0x10, 0,
11731 AC_VERB_SET_AMP_GAIN_MUTE,
11734 snd_hda_codec_write(codec, 0x0f, 0,
11735 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11736 snd_hda_codec_write(codec, 0x10, 0,
11737 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11740 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11741 if (line_nid == 0x14)
11742 dac_vol2 = AMP_OUT_ZERO;
11743 else if (line_nid == 0x15)
11744 dac_vol1 = AMP_OUT_ZERO;
11745 if (hp_nid == 0x14)
11746 dac_vol2 = AMP_OUT_ZERO;
11747 else if (hp_nid == 0x15)
11748 dac_vol1 = AMP_OUT_ZERO;
11749 if (line_nid != 0x16 || hp_nid != 0x16 ||
11750 spec->autocfg.line_out_pins[1] != 0x16 ||
11751 spec->autocfg.line_out_pins[2] != 0x16)
11752 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11754 snd_hda_codec_write(codec, 0x02, 0,
11755 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11756 snd_hda_codec_write(codec, 0x03, 0,
11757 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11760 /* pcm configuration: identiacal with ALC880 */
11761 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11762 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11763 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11764 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11767 * BIOS auto configuration
11769 static int alc268_parse_auto_config(struct hda_codec *codec)
11771 struct alc_spec *spec = codec->spec;
11773 static hda_nid_t alc268_ignore[] = { 0 };
11775 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11779 if (!spec->autocfg.line_outs)
11780 return 0; /* can't find valid BIOS pin config */
11782 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11785 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11789 spec->multiout.max_channels = 2;
11791 /* digital only support output */
11792 if (spec->autocfg.dig_out_pin)
11793 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11795 if (spec->kctls.list)
11796 add_mixer(spec, spec->kctls.list);
11798 if (spec->autocfg.speaker_pins[0] != 0x1d)
11799 add_mixer(spec, alc268_beep_mixer);
11801 add_verb(spec, alc268_volume_init_verbs);
11802 spec->num_mux_defs = 1;
11803 spec->input_mux = &spec->private_imux[0];
11805 err = alc_auto_add_mic_boost(codec);
11809 store_pin_configs(codec);
11813 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
11814 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
11815 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
11817 /* init callback for auto-configuration model -- overriding the default init */
11818 static void alc268_auto_init(struct hda_codec *codec)
11820 struct alc_spec *spec = codec->spec;
11821 alc268_auto_init_multi_out(codec);
11822 alc268_auto_init_hp_out(codec);
11823 alc268_auto_init_mono_speaker_out(codec);
11824 alc268_auto_init_analog_input(codec);
11825 if (spec->unsol_event)
11826 alc_inithook(codec);
11830 * configuration and preset
11832 static const char *alc268_models[ALC268_MODEL_LAST] = {
11833 [ALC267_QUANTA_IL1] = "quanta-il1",
11834 [ALC268_3ST] = "3stack",
11835 [ALC268_TOSHIBA] = "toshiba",
11836 [ALC268_ACER] = "acer",
11837 [ALC268_ACER_DMIC] = "acer-dmic",
11838 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11839 [ALC268_DELL] = "dell",
11840 [ALC268_ZEPTO] = "zepto",
11841 #ifdef CONFIG_SND_DEBUG
11842 [ALC268_TEST] = "test",
11844 [ALC268_AUTO] = "auto",
11847 static struct snd_pci_quirk alc268_cfg_tbl[] = {
11848 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11849 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11850 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11851 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11852 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11853 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11854 ALC268_ACER_ASPIRE_ONE),
11855 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11856 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
11857 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11858 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11859 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11860 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11861 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11862 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11863 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11864 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11865 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11869 static struct alc_config_preset alc268_presets[] = {
11870 [ALC267_QUANTA_IL1] = {
11871 .mixers = { alc267_quanta_il1_mixer },
11872 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11873 alc267_quanta_il1_verbs },
11874 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11875 .dac_nids = alc268_dac_nids,
11876 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11877 .adc_nids = alc268_adc_nids_alt,
11879 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11880 .channel_mode = alc268_modes,
11881 .input_mux = &alc268_capture_source,
11882 .unsol_event = alc267_quanta_il1_unsol_event,
11883 .init_hook = alc267_quanta_il1_automute,
11886 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11887 alc268_beep_mixer },
11888 .init_verbs = { alc268_base_init_verbs },
11889 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11890 .dac_nids = alc268_dac_nids,
11891 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11892 .adc_nids = alc268_adc_nids_alt,
11893 .capsrc_nids = alc268_capsrc_nids,
11895 .dig_out_nid = ALC268_DIGOUT_NID,
11896 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11897 .channel_mode = alc268_modes,
11898 .input_mux = &alc268_capture_source,
11900 [ALC268_TOSHIBA] = {
11901 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11902 alc268_beep_mixer },
11903 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11904 alc268_toshiba_verbs },
11905 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11906 .dac_nids = alc268_dac_nids,
11907 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11908 .adc_nids = alc268_adc_nids_alt,
11909 .capsrc_nids = alc268_capsrc_nids,
11911 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11912 .channel_mode = alc268_modes,
11913 .input_mux = &alc268_capture_source,
11914 .unsol_event = alc268_toshiba_unsol_event,
11915 .init_hook = alc268_toshiba_automute,
11918 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11919 alc268_beep_mixer },
11920 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11921 alc268_acer_verbs },
11922 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11923 .dac_nids = alc268_dac_nids,
11924 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11925 .adc_nids = alc268_adc_nids_alt,
11926 .capsrc_nids = alc268_capsrc_nids,
11928 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11929 .channel_mode = alc268_modes,
11930 .input_mux = &alc268_acer_capture_source,
11931 .unsol_event = alc268_acer_unsol_event,
11932 .init_hook = alc268_acer_init_hook,
11934 [ALC268_ACER_DMIC] = {
11935 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
11936 alc268_beep_mixer },
11937 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11938 alc268_acer_verbs },
11939 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11940 .dac_nids = alc268_dac_nids,
11941 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11942 .adc_nids = alc268_adc_nids_alt,
11943 .capsrc_nids = alc268_capsrc_nids,
11945 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11946 .channel_mode = alc268_modes,
11947 .input_mux = &alc268_acer_dmic_capture_source,
11948 .unsol_event = alc268_acer_unsol_event,
11949 .init_hook = alc268_acer_init_hook,
11951 [ALC268_ACER_ASPIRE_ONE] = {
11952 .mixers = { alc268_acer_aspire_one_mixer,
11953 alc268_capture_alt_mixer },
11954 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11955 alc268_acer_aspire_one_verbs },
11956 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11957 .dac_nids = alc268_dac_nids,
11958 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11959 .adc_nids = alc268_adc_nids_alt,
11960 .capsrc_nids = alc268_capsrc_nids,
11962 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11963 .channel_mode = alc268_modes,
11964 .input_mux = &alc268_acer_lc_capture_source,
11965 .unsol_event = alc268_acer_lc_unsol_event,
11966 .init_hook = alc268_acer_lc_init_hook,
11969 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
11970 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11971 alc268_dell_verbs },
11972 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11973 .dac_nids = alc268_dac_nids,
11975 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11976 .channel_mode = alc268_modes,
11977 .unsol_event = alc268_dell_unsol_event,
11978 .init_hook = alc268_dell_init_hook,
11979 .input_mux = &alc268_capture_source,
11982 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11983 alc268_beep_mixer },
11984 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11985 alc268_toshiba_verbs },
11986 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11987 .dac_nids = alc268_dac_nids,
11988 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11989 .adc_nids = alc268_adc_nids_alt,
11990 .capsrc_nids = alc268_capsrc_nids,
11992 .dig_out_nid = ALC268_DIGOUT_NID,
11993 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11994 .channel_mode = alc268_modes,
11995 .input_mux = &alc268_capture_source,
11996 .unsol_event = alc268_toshiba_unsol_event,
11997 .init_hook = alc268_toshiba_automute
11999 #ifdef CONFIG_SND_DEBUG
12001 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12002 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12003 alc268_volume_init_verbs },
12004 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12005 .dac_nids = alc268_dac_nids,
12006 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12007 .adc_nids = alc268_adc_nids_alt,
12008 .capsrc_nids = alc268_capsrc_nids,
12010 .dig_out_nid = ALC268_DIGOUT_NID,
12011 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12012 .channel_mode = alc268_modes,
12013 .input_mux = &alc268_capture_source,
12018 static int patch_alc268(struct hda_codec *codec)
12020 struct alc_spec *spec;
12024 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12028 codec->spec = spec;
12030 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12034 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12035 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
12036 "trying auto-probe from BIOS...\n");
12037 board_config = ALC268_AUTO;
12040 if (board_config == ALC268_AUTO) {
12041 /* automatic parse from the BIOS config */
12042 err = alc268_parse_auto_config(codec);
12048 "hda_codec: Cannot set up configuration "
12049 "from BIOS. Using base mode...\n");
12050 board_config = ALC268_3ST;
12054 if (board_config != ALC268_AUTO)
12055 setup_preset(spec, &alc268_presets[board_config]);
12057 if (codec->vendor_id == 0x10ec0267) {
12058 spec->stream_name_analog = "ALC267 Analog";
12059 spec->stream_name_digital = "ALC267 Digital";
12061 spec->stream_name_analog = "ALC268 Analog";
12062 spec->stream_name_digital = "ALC268 Digital";
12065 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12066 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12067 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12069 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12071 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12072 /* override the amp caps for beep generator */
12073 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12074 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12075 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12076 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12077 (0 << AC_AMPCAP_MUTE_SHIFT));
12079 if (!spec->adc_nids && spec->input_mux) {
12080 /* check whether NID 0x07 is valid */
12081 unsigned int wcap = get_wcaps(codec, 0x07);
12085 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12086 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12087 spec->adc_nids = alc268_adc_nids_alt;
12088 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12089 add_mixer(spec, alc268_capture_alt_mixer);
12091 spec->adc_nids = alc268_adc_nids;
12092 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12093 add_mixer(spec, alc268_capture_mixer);
12095 spec->capsrc_nids = alc268_capsrc_nids;
12096 /* set default input source */
12097 for (i = 0; i < spec->num_adc_nids; i++)
12098 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12099 0, AC_VERB_SET_CONNECT_SEL,
12100 spec->input_mux->items[0].index);
12103 spec->vmaster_nid = 0x02;
12105 codec->patch_ops = alc_patch_ops;
12106 if (board_config == ALC268_AUTO)
12107 spec->init_hook = alc268_auto_init;
12109 codec->proc_widget_hook = print_realtek_coef;
12115 * ALC269 channel source setting (2 channel)
12117 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12119 #define alc269_dac_nids alc260_dac_nids
12121 static hda_nid_t alc269_adc_nids[1] = {
12126 static hda_nid_t alc269_capsrc_nids[1] = {
12130 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12134 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12142 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12150 #define alc269_modes alc260_modes
12151 #define alc269_capture_source alc880_lg_lw_capture_source
12153 static struct snd_kcontrol_new alc269_base_mixer[] = {
12154 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12155 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12156 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12157 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12158 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12159 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12160 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
12161 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
12162 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12163 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12164 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12165 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12166 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12167 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12171 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12172 /* output mixer control */
12173 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12175 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12176 .name = "Master Playback Switch",
12177 .info = snd_hda_mixer_amp_switch_info,
12178 .get = snd_hda_mixer_amp_switch_get,
12179 .put = alc268_acer_master_sw_put,
12180 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12182 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12183 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12184 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12185 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12186 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12187 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12188 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
12189 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
12193 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12194 /* output mixer control */
12195 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12197 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12198 .name = "Master Playback Switch",
12199 .info = snd_hda_mixer_amp_switch_info,
12200 .get = snd_hda_mixer_amp_switch_get,
12201 .put = alc268_acer_master_sw_put,
12202 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12204 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12205 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12206 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12207 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12208 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12209 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12210 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12211 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12212 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12213 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
12214 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
12218 /* bind volumes of both NID 0x0c and 0x0d */
12219 static struct hda_bind_ctls alc269_epc_bind_vol = {
12220 .ops = &snd_hda_bind_vol,
12222 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12223 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12228 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12229 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12230 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12231 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12235 /* capture mixer elements */
12236 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12237 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12238 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12239 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12244 static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12245 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12246 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12247 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
12252 static struct snd_kcontrol_new alc269_beep_mixer[] = {
12253 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
12254 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
12258 static struct hda_verb alc269_quanta_fl1_verbs[] = {
12259 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12260 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12261 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12262 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12263 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12264 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12268 static struct hda_verb alc269_lifebook_verbs[] = {
12269 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12270 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12271 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12272 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12273 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12274 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12275 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12276 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12277 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12278 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12282 /* toggle speaker-output according to the hp-jack state */
12283 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12285 unsigned int present;
12286 unsigned char bits;
12288 present = snd_hda_codec_read(codec, 0x15, 0,
12289 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12290 bits = present ? AMP_IN_MUTE(0) : 0;
12291 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12292 AMP_IN_MUTE(0), bits);
12293 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12294 AMP_IN_MUTE(0), bits);
12296 snd_hda_codec_write(codec, 0x20, 0,
12297 AC_VERB_SET_COEF_INDEX, 0x0c);
12298 snd_hda_codec_write(codec, 0x20, 0,
12299 AC_VERB_SET_PROC_COEF, 0x680);
12301 snd_hda_codec_write(codec, 0x20, 0,
12302 AC_VERB_SET_COEF_INDEX, 0x0c);
12303 snd_hda_codec_write(codec, 0x20, 0,
12304 AC_VERB_SET_PROC_COEF, 0x480);
12307 /* toggle speaker-output according to the hp-jacks state */
12308 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12310 unsigned int present;
12311 unsigned char bits;
12313 /* Check laptop headphone socket */
12314 present = snd_hda_codec_read(codec, 0x15, 0,
12315 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12317 /* Check port replicator headphone socket */
12318 present |= snd_hda_codec_read(codec, 0x1a, 0,
12319 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12321 bits = present ? AMP_IN_MUTE(0) : 0;
12322 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12323 AMP_IN_MUTE(0), bits);
12324 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12325 AMP_IN_MUTE(0), bits);
12327 snd_hda_codec_write(codec, 0x20, 0,
12328 AC_VERB_SET_COEF_INDEX, 0x0c);
12329 snd_hda_codec_write(codec, 0x20, 0,
12330 AC_VERB_SET_PROC_COEF, 0x680);
12332 snd_hda_codec_write(codec, 0x20, 0,
12333 AC_VERB_SET_COEF_INDEX, 0x0c);
12334 snd_hda_codec_write(codec, 0x20, 0,
12335 AC_VERB_SET_PROC_COEF, 0x480);
12338 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12340 unsigned int present;
12342 present = snd_hda_codec_read(codec, 0x18, 0,
12343 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12344 snd_hda_codec_write(codec, 0x23, 0,
12345 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12348 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12350 unsigned int present_laptop;
12351 unsigned int present_dock;
12353 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12354 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12356 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12357 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12359 /* Laptop mic port overrides dock mic port, design decision */
12361 snd_hda_codec_write(codec, 0x23, 0,
12362 AC_VERB_SET_CONNECT_SEL, 0x3);
12363 if (present_laptop)
12364 snd_hda_codec_write(codec, 0x23, 0,
12365 AC_VERB_SET_CONNECT_SEL, 0x0);
12366 if (!present_dock && !present_laptop)
12367 snd_hda_codec_write(codec, 0x23, 0,
12368 AC_VERB_SET_CONNECT_SEL, 0x1);
12371 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12374 if ((res >> 26) == ALC880_HP_EVENT)
12375 alc269_quanta_fl1_speaker_automute(codec);
12376 if ((res >> 26) == ALC880_MIC_EVENT)
12377 alc269_quanta_fl1_mic_automute(codec);
12380 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12383 if ((res >> 26) == ALC880_HP_EVENT)
12384 alc269_lifebook_speaker_automute(codec);
12385 if ((res >> 26) == ALC880_MIC_EVENT)
12386 alc269_lifebook_mic_autoswitch(codec);
12389 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12391 alc269_quanta_fl1_speaker_automute(codec);
12392 alc269_quanta_fl1_mic_automute(codec);
12395 static void alc269_lifebook_init_hook(struct hda_codec *codec)
12397 alc269_lifebook_speaker_automute(codec);
12398 alc269_lifebook_mic_autoswitch(codec);
12401 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12402 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12403 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12404 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12405 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12406 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12407 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12408 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12412 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12413 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12414 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12415 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12416 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12417 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12418 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12422 /* toggle speaker-output according to the hp-jack state */
12423 static void alc269_speaker_automute(struct hda_codec *codec)
12425 unsigned int present;
12426 unsigned char bits;
12428 present = snd_hda_codec_read(codec, 0x15, 0,
12429 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12430 bits = present ? AMP_IN_MUTE(0) : 0;
12431 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12432 AMP_IN_MUTE(0), bits);
12433 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12434 AMP_IN_MUTE(0), bits);
12437 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12439 unsigned int present;
12441 present = snd_hda_codec_read(codec, 0x18, 0,
12442 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12443 snd_hda_codec_write(codec, 0x23, 0,
12444 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12447 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12449 unsigned int present;
12451 present = snd_hda_codec_read(codec, 0x18, 0,
12452 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12453 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12454 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12455 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12456 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12459 /* unsolicited event for HP jack sensing */
12460 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12463 if ((res >> 26) == ALC880_HP_EVENT)
12464 alc269_speaker_automute(codec);
12466 if ((res >> 26) == ALC880_MIC_EVENT)
12467 alc269_eeepc_dmic_automute(codec);
12470 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12472 alc269_speaker_automute(codec);
12473 alc269_eeepc_dmic_automute(codec);
12476 /* unsolicited event for HP jack sensing */
12477 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12480 if ((res >> 26) == ALC880_HP_EVENT)
12481 alc269_speaker_automute(codec);
12483 if ((res >> 26) == ALC880_MIC_EVENT)
12484 alc269_eeepc_amic_automute(codec);
12487 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12489 alc269_speaker_automute(codec);
12490 alc269_eeepc_amic_automute(codec);
12494 * generic initialization of ADC, input mixers and output mixers
12496 static struct hda_verb alc269_init_verbs[] = {
12498 * Unmute ADC0 and set the default input to mic-in
12500 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12502 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12503 * analog-loopback mixer widget
12504 * Note: PASD motherboards uses the Line In 2 as the input for
12505 * front panel mic (mic 2)
12507 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12508 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12509 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12510 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12511 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12512 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12515 * Set up output mixers (0x0c - 0x0e)
12517 /* set vol=0 to output mixers */
12518 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12519 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12521 /* set up input amps for analog loopback */
12522 /* Amp Indices: DAC = 0, mixer = 1 */
12523 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12524 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12525 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12526 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12527 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12528 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12530 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12531 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12532 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12533 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12534 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12535 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12536 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12538 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12539 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12540 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12541 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12542 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12543 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12544 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12546 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12547 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12549 /* FIXME: use matrix-type input source selection */
12550 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12551 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12552 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12553 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12554 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12555 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12558 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12559 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12563 /* add playback controls from the parsed DAC table */
12564 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12565 const struct auto_pin_cfg *cfg)
12570 spec->multiout.num_dacs = 1; /* only use one dac */
12571 spec->multiout.dac_nids = spec->private_dac_nids;
12572 spec->multiout.dac_nids[0] = 2;
12574 nid = cfg->line_out_pins[0];
12576 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12577 "Front Playback Volume",
12578 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12581 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12582 "Front Playback Switch",
12583 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12588 nid = cfg->speaker_pins[0];
12590 if (!cfg->line_out_pins[0]) {
12591 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12592 "Speaker Playback Volume",
12593 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12599 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12600 "Speaker Playback Switch",
12601 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12606 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12607 "Speaker Playback Switch",
12608 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12614 nid = cfg->hp_pins[0];
12616 /* spec->multiout.hp_nid = 2; */
12617 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12618 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12619 "Headphone Playback Volume",
12620 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12626 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12627 "Headphone Playback Switch",
12628 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12633 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12634 "Headphone Playback Switch",
12635 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12644 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12645 const struct auto_pin_cfg *cfg)
12649 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12652 /* digital-mic input pin is excluded in alc880_auto_create..()
12653 * because it's under 0x18
12655 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12656 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12657 struct hda_input_mux *imux = &spec->private_imux[0];
12658 imux->items[imux->num_items].label = "Int Mic";
12659 imux->items[imux->num_items].index = 0x05;
12665 #ifdef CONFIG_SND_HDA_POWER_SAVE
12666 #define alc269_loopbacks alc880_loopbacks
12669 /* pcm configuration: identiacal with ALC880 */
12670 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12671 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12672 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12673 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12676 * BIOS auto configuration
12678 static int alc269_parse_auto_config(struct hda_codec *codec)
12680 struct alc_spec *spec = codec->spec;
12682 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12684 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12689 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12692 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12696 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12698 if (spec->autocfg.dig_out_pin)
12699 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12701 if (spec->kctls.list)
12702 add_mixer(spec, spec->kctls.list);
12704 /* create a beep mixer control if the pin 0x1d isn't assigned */
12705 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12706 if (spec->autocfg.input_pins[i] == 0x1d)
12708 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12709 add_mixer(spec, alc269_beep_mixer);
12711 add_verb(spec, alc269_init_verbs);
12712 spec->num_mux_defs = 1;
12713 spec->input_mux = &spec->private_imux[0];
12714 /* set default input source */
12715 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12716 0, AC_VERB_SET_CONNECT_SEL,
12717 spec->input_mux->items[0].index);
12719 err = alc_auto_add_mic_boost(codec);
12723 if (!spec->cap_mixer)
12724 set_capture_mixer(spec);
12726 store_pin_configs(codec);
12730 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12731 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12732 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12735 /* init callback for auto-configuration model -- overriding the default init */
12736 static void alc269_auto_init(struct hda_codec *codec)
12738 struct alc_spec *spec = codec->spec;
12739 alc269_auto_init_multi_out(codec);
12740 alc269_auto_init_hp_out(codec);
12741 alc269_auto_init_analog_input(codec);
12742 if (spec->unsol_event)
12743 alc_inithook(codec);
12747 * configuration and preset
12749 static const char *alc269_models[ALC269_MODEL_LAST] = {
12750 [ALC269_BASIC] = "basic",
12751 [ALC269_QUANTA_FL1] = "quanta",
12752 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12753 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
12754 [ALC269_FUJITSU] = "fujitsu",
12755 [ALC269_LIFEBOOK] = "lifebook"
12758 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12759 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12760 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12761 ALC269_ASUS_EEEPC_P703),
12762 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12763 ALC269_ASUS_EEEPC_P901),
12764 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12765 ALC269_ASUS_EEEPC_P901),
12766 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12767 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
12771 static struct alc_config_preset alc269_presets[] = {
12773 .mixers = { alc269_base_mixer },
12774 .init_verbs = { alc269_init_verbs },
12775 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12776 .dac_nids = alc269_dac_nids,
12778 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12779 .channel_mode = alc269_modes,
12780 .input_mux = &alc269_capture_source,
12782 [ALC269_QUANTA_FL1] = {
12783 .mixers = { alc269_quanta_fl1_mixer },
12784 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12785 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12786 .dac_nids = alc269_dac_nids,
12788 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12789 .channel_mode = alc269_modes,
12790 .input_mux = &alc269_capture_source,
12791 .unsol_event = alc269_quanta_fl1_unsol_event,
12792 .init_hook = alc269_quanta_fl1_init_hook,
12794 [ALC269_ASUS_EEEPC_P703] = {
12795 .mixers = { alc269_eeepc_mixer },
12796 .cap_mixer = alc269_epc_capture_mixer,
12797 .init_verbs = { alc269_init_verbs,
12798 alc269_eeepc_amic_init_verbs },
12799 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12800 .dac_nids = alc269_dac_nids,
12802 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12803 .channel_mode = alc269_modes,
12804 .input_mux = &alc269_eeepc_amic_capture_source,
12805 .unsol_event = alc269_eeepc_amic_unsol_event,
12806 .init_hook = alc269_eeepc_amic_inithook,
12808 [ALC269_ASUS_EEEPC_P901] = {
12809 .mixers = { alc269_eeepc_mixer },
12810 .cap_mixer = alc269_epc_capture_mixer,
12811 .init_verbs = { alc269_init_verbs,
12812 alc269_eeepc_dmic_init_verbs },
12813 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12814 .dac_nids = alc269_dac_nids,
12816 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12817 .channel_mode = alc269_modes,
12818 .input_mux = &alc269_eeepc_dmic_capture_source,
12819 .unsol_event = alc269_eeepc_dmic_unsol_event,
12820 .init_hook = alc269_eeepc_dmic_inithook,
12822 [ALC269_FUJITSU] = {
12823 .mixers = { alc269_fujitsu_mixer, alc269_beep_mixer },
12824 .cap_mixer = alc269_epc_capture_mixer,
12825 .init_verbs = { alc269_init_verbs,
12826 alc269_eeepc_dmic_init_verbs },
12827 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12828 .dac_nids = alc269_dac_nids,
12830 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12831 .channel_mode = alc269_modes,
12832 .input_mux = &alc269_eeepc_dmic_capture_source,
12833 .unsol_event = alc269_eeepc_dmic_unsol_event,
12834 .init_hook = alc269_eeepc_dmic_inithook,
12836 [ALC269_LIFEBOOK] = {
12837 .mixers = { alc269_lifebook_mixer },
12838 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
12839 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12840 .dac_nids = alc269_dac_nids,
12842 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12843 .channel_mode = alc269_modes,
12844 .input_mux = &alc269_capture_source,
12845 .unsol_event = alc269_lifebook_unsol_event,
12846 .init_hook = alc269_lifebook_init_hook,
12850 static int patch_alc269(struct hda_codec *codec)
12852 struct alc_spec *spec;
12856 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12860 codec->spec = spec;
12862 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12864 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12868 if (board_config < 0) {
12869 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12870 "trying auto-probe from BIOS...\n");
12871 board_config = ALC269_AUTO;
12874 if (board_config == ALC269_AUTO) {
12875 /* automatic parse from the BIOS config */
12876 err = alc269_parse_auto_config(codec);
12882 "hda_codec: Cannot set up configuration "
12883 "from BIOS. Using base mode...\n");
12884 board_config = ALC269_BASIC;
12888 if (board_config != ALC269_AUTO)
12889 setup_preset(spec, &alc269_presets[board_config]);
12891 spec->stream_name_analog = "ALC269 Analog";
12892 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12893 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12895 spec->stream_name_digital = "ALC269 Digital";
12896 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12897 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12899 spec->adc_nids = alc269_adc_nids;
12900 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12901 spec->capsrc_nids = alc269_capsrc_nids;
12902 if (!spec->cap_mixer)
12903 set_capture_mixer(spec);
12905 codec->patch_ops = alc_patch_ops;
12906 if (board_config == ALC269_AUTO)
12907 spec->init_hook = alc269_auto_init;
12908 #ifdef CONFIG_SND_HDA_POWER_SAVE
12909 if (!spec->loopback.amplist)
12910 spec->loopback.amplist = alc269_loopbacks;
12912 codec->proc_widget_hook = print_realtek_coef;
12918 * ALC861 channel source setting (2/6 channel selection for 3-stack)
12922 * set the path ways for 2 channel output
12923 * need to set the codec line out and mic 1 pin widgets to inputs
12925 static struct hda_verb alc861_threestack_ch2_init[] = {
12926 /* set pin widget 1Ah (line in) for input */
12927 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12928 /* set pin widget 18h (mic1/2) for input, for mic also enable
12931 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12933 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12935 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12936 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12942 * need to set the codec line out and mic 1 pin widgets to outputs
12944 static struct hda_verb alc861_threestack_ch6_init[] = {
12945 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12946 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12947 /* set pin widget 18h (mic1) for output (CLFE)*/
12948 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12950 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12951 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12953 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12955 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12956 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12961 static struct hda_channel_mode alc861_threestack_modes[2] = {
12962 { 2, alc861_threestack_ch2_init },
12963 { 6, alc861_threestack_ch6_init },
12965 /* Set mic1 as input and unmute the mixer */
12966 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12967 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12968 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12971 /* Set mic1 as output and mute mixer */
12972 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12973 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12974 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12978 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12979 { 2, alc861_uniwill_m31_ch2_init },
12980 { 4, alc861_uniwill_m31_ch4_init },
12983 /* Set mic1 and line-in as input and unmute the mixer */
12984 static struct hda_verb alc861_asus_ch2_init[] = {
12985 /* set pin widget 1Ah (line in) for input */
12986 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12987 /* set pin widget 18h (mic1/2) for input, for mic also enable
12990 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12992 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12994 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12995 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12999 /* Set mic1 nad line-in as output and mute mixer */
13000 static struct hda_verb alc861_asus_ch6_init[] = {
13001 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13002 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13003 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13004 /* set pin widget 18h (mic1) for output (CLFE)*/
13005 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13006 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13007 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13008 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13010 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13012 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13013 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13018 static struct hda_channel_mode alc861_asus_modes[2] = {
13019 { 2, alc861_asus_ch2_init },
13020 { 6, alc861_asus_ch6_init },
13025 static struct snd_kcontrol_new alc861_base_mixer[] = {
13026 /* output mixer control */
13027 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13028 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13029 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13030 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13031 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13033 /*Input mixer control */
13034 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13035 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13036 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13037 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13038 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13039 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13040 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13041 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13042 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13043 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13048 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13049 /* output mixer control */
13050 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13051 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13052 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13053 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13054 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13056 /* Input mixer control */
13057 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13058 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13059 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13060 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13061 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13062 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13063 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13064 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13065 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13066 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13069 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13070 .name = "Channel Mode",
13071 .info = alc_ch_mode_info,
13072 .get = alc_ch_mode_get,
13073 .put = alc_ch_mode_put,
13074 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13079 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13080 /* output mixer control */
13081 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13082 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13083 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13088 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13089 /* output mixer control */
13090 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13091 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13092 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13093 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13094 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13096 /* Input mixer control */
13097 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13098 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13099 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13100 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13101 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13102 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13103 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13104 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13105 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13106 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13109 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13110 .name = "Channel Mode",
13111 .info = alc_ch_mode_info,
13112 .get = alc_ch_mode_get,
13113 .put = alc_ch_mode_put,
13114 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13119 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13120 /* output mixer control */
13121 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13122 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13123 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13124 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13125 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13127 /* Input mixer control */
13128 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13129 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13130 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13131 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13132 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13133 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13134 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13135 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13136 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13137 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13140 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13141 .name = "Channel Mode",
13142 .info = alc_ch_mode_info,
13143 .get = alc_ch_mode_get,
13144 .put = alc_ch_mode_put,
13145 .private_value = ARRAY_SIZE(alc861_asus_modes),
13150 /* additional mixer */
13151 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13152 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13153 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13154 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
13155 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
13160 * generic initialization of ADC, input mixers and output mixers
13162 static struct hda_verb alc861_base_init_verbs[] = {
13164 * Unmute ADC0 and set the default input to mic-in
13166 /* port-A for surround (rear panel) */
13167 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13168 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13169 /* port-B for mic-in (rear panel) with vref */
13170 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13171 /* port-C for line-in (rear panel) */
13172 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13173 /* port-D for Front */
13174 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13175 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13176 /* port-E for HP out (front panel) */
13177 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13178 /* route front PCM to HP */
13179 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13180 /* port-F for mic-in (front panel) with vref */
13181 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13182 /* port-G for CLFE (rear panel) */
13183 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13184 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13185 /* port-H for side (rear panel) */
13186 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13187 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13189 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13190 /* route front mic to ADC1*/
13191 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13192 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13194 /* Unmute DAC0~3 & spdif out*/
13195 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13196 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13197 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13198 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13199 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13201 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13202 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13203 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13204 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13205 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13207 /* Unmute Stereo Mixer 15 */
13208 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13209 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13210 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13211 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13213 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13214 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13215 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13216 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13217 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13218 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13219 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13220 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13221 /* hp used DAC 3 (Front) */
13222 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13223 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13228 static struct hda_verb alc861_threestack_init_verbs[] = {
13230 * Unmute ADC0 and set the default input to mic-in
13232 /* port-A for surround (rear panel) */
13233 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13234 /* port-B for mic-in (rear panel) with vref */
13235 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13236 /* port-C for line-in (rear panel) */
13237 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13238 /* port-D for Front */
13239 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13240 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13241 /* port-E for HP out (front panel) */
13242 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13243 /* route front PCM to HP */
13244 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13245 /* port-F for mic-in (front panel) with vref */
13246 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13247 /* port-G for CLFE (rear panel) */
13248 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13249 /* port-H for side (rear panel) */
13250 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13252 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13253 /* route front mic to ADC1*/
13254 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13255 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13256 /* Unmute DAC0~3 & spdif out*/
13257 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13258 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13259 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13260 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13261 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13263 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13264 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13265 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13266 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13267 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13269 /* Unmute Stereo Mixer 15 */
13270 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13271 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13272 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13273 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13275 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13276 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13277 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13278 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13279 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13280 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13281 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13282 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13283 /* hp used DAC 3 (Front) */
13284 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13285 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13289 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13291 * Unmute ADC0 and set the default input to mic-in
13293 /* port-A for surround (rear panel) */
13294 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13295 /* port-B for mic-in (rear panel) with vref */
13296 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13297 /* port-C for line-in (rear panel) */
13298 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13299 /* port-D for Front */
13300 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13301 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13302 /* port-E for HP out (front panel) */
13303 /* this has to be set to VREF80 */
13304 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13305 /* route front PCM to HP */
13306 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13307 /* port-F for mic-in (front panel) with vref */
13308 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13309 /* port-G for CLFE (rear panel) */
13310 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13311 /* port-H for side (rear panel) */
13312 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13314 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13315 /* route front mic to ADC1*/
13316 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13317 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13318 /* Unmute DAC0~3 & spdif out*/
13319 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13320 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13321 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13322 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13325 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13326 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13327 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13328 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13329 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13331 /* Unmute Stereo Mixer 15 */
13332 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13333 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13334 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13335 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13337 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13338 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13339 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13340 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13341 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13342 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13343 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13344 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13345 /* hp used DAC 3 (Front) */
13346 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13347 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13351 static struct hda_verb alc861_asus_init_verbs[] = {
13353 * Unmute ADC0 and set the default input to mic-in
13355 /* port-A for surround (rear panel)
13356 * according to codec#0 this is the HP jack
13358 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13359 /* route front PCM to HP */
13360 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13361 /* port-B for mic-in (rear panel) with vref */
13362 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13363 /* port-C for line-in (rear panel) */
13364 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13365 /* port-D for Front */
13366 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13367 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13368 /* port-E for HP out (front panel) */
13369 /* this has to be set to VREF80 */
13370 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13371 /* route front PCM to HP */
13372 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13373 /* port-F for mic-in (front panel) with vref */
13374 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13375 /* port-G for CLFE (rear panel) */
13376 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13377 /* port-H for side (rear panel) */
13378 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13380 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13381 /* route front mic to ADC1*/
13382 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13383 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13384 /* Unmute DAC0~3 & spdif out*/
13385 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13386 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13387 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13388 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13389 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13390 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13391 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13392 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13393 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13394 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13396 /* Unmute Stereo Mixer 15 */
13397 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13398 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13399 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13400 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13402 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13403 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13404 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13405 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13406 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13407 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13408 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13409 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13410 /* hp used DAC 3 (Front) */
13411 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13412 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13416 /* additional init verbs for ASUS laptops */
13417 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13418 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13419 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13424 * generic initialization of ADC, input mixers and output mixers
13426 static struct hda_verb alc861_auto_init_verbs[] = {
13428 * Unmute ADC0 and set the default input to mic-in
13430 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13431 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13433 /* Unmute DAC0~3 & spdif out*/
13434 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13435 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13436 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13437 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13438 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13440 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13441 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13442 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13443 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13444 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13446 /* Unmute Stereo Mixer 15 */
13447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13448 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13449 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13450 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13452 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13453 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13454 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13455 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13456 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13457 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13458 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13459 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13461 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13462 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13463 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13464 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13465 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13466 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13467 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13468 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13470 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13475 static struct hda_verb alc861_toshiba_init_verbs[] = {
13476 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13481 /* toggle speaker-output according to the hp-jack state */
13482 static void alc861_toshiba_automute(struct hda_codec *codec)
13484 unsigned int present;
13486 present = snd_hda_codec_read(codec, 0x0f, 0,
13487 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13488 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13489 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13490 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13491 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13494 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13497 if ((res >> 26) == ALC880_HP_EVENT)
13498 alc861_toshiba_automute(codec);
13501 /* pcm configuration: identiacal with ALC880 */
13502 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13503 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13504 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13505 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13508 #define ALC861_DIGOUT_NID 0x07
13510 static struct hda_channel_mode alc861_8ch_modes[1] = {
13514 static hda_nid_t alc861_dac_nids[4] = {
13515 /* front, surround, clfe, side */
13516 0x03, 0x06, 0x05, 0x04
13519 static hda_nid_t alc660_dac_nids[3] = {
13520 /* front, clfe, surround */
13524 static hda_nid_t alc861_adc_nids[1] = {
13529 static struct hda_input_mux alc861_capture_source = {
13533 { "Front Mic", 0x3 },
13540 /* fill in the dac_nids table from the parsed pin configuration */
13541 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13542 const struct auto_pin_cfg *cfg)
13547 spec->multiout.dac_nids = spec->private_dac_nids;
13548 for (i = 0; i < cfg->line_outs; i++) {
13549 nid = cfg->line_out_pins[i];
13551 if (i >= ARRAY_SIZE(alc861_dac_nids))
13553 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13556 spec->multiout.num_dacs = cfg->line_outs;
13560 /* add playback controls from the parsed DAC table */
13561 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13562 const struct auto_pin_cfg *cfg)
13565 static const char *chname[4] = {
13566 "Front", "Surround", NULL /*CLFE*/, "Side"
13571 for (i = 0; i < cfg->line_outs; i++) {
13572 nid = spec->multiout.dac_nids[i];
13577 err = add_control(spec, ALC_CTL_BIND_MUTE,
13578 "Center Playback Switch",
13579 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13583 err = add_control(spec, ALC_CTL_BIND_MUTE,
13584 "LFE Playback Switch",
13585 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13590 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13592 if (nid == alc861_dac_nids[idx])
13594 sprintf(name, "%s Playback Switch", chname[idx]);
13595 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13596 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13605 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13613 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13615 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13616 "Headphone Playback Switch",
13617 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13620 spec->multiout.hp_nid = nid;
13625 /* create playback/capture controls for input pins */
13626 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13627 const struct auto_pin_cfg *cfg)
13629 struct hda_input_mux *imux = &spec->private_imux[0];
13630 int i, err, idx, idx1;
13632 for (i = 0; i < AUTO_PIN_LAST; i++) {
13633 switch (cfg->input_pins[i]) {
13636 idx = 2; /* Line In */
13640 idx = 2; /* Line In */
13644 idx = 1; /* Mic In */
13648 idx = 1; /* Mic In */
13658 err = new_analog_input(spec, cfg->input_pins[i],
13659 auto_pin_cfg_labels[i], idx, 0x15);
13663 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13664 imux->items[imux->num_items].index = idx1;
13670 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13672 int pin_type, int dac_idx)
13674 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13676 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13680 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13682 struct alc_spec *spec = codec->spec;
13685 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13686 for (i = 0; i < spec->autocfg.line_outs; i++) {
13687 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13688 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13690 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13691 spec->multiout.dac_nids[i]);
13695 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13697 struct alc_spec *spec = codec->spec;
13700 pin = spec->autocfg.hp_pins[0];
13701 if (pin) /* connect to front */
13702 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13703 spec->multiout.dac_nids[0]);
13704 pin = spec->autocfg.speaker_pins[0];
13706 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13709 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13711 struct alc_spec *spec = codec->spec;
13714 for (i = 0; i < AUTO_PIN_LAST; i++) {
13715 hda_nid_t nid = spec->autocfg.input_pins[i];
13716 if (nid >= 0x0c && nid <= 0x11) {
13717 snd_hda_codec_write(codec, nid, 0,
13718 AC_VERB_SET_PIN_WIDGET_CONTROL,
13719 i <= AUTO_PIN_FRONT_MIC ?
13720 PIN_VREF80 : PIN_IN);
13725 /* parse the BIOS configuration and set up the alc_spec */
13726 /* return 1 if successful, 0 if the proper config is not found,
13727 * or a negative error code
13729 static int alc861_parse_auto_config(struct hda_codec *codec)
13731 struct alc_spec *spec = codec->spec;
13733 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13735 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13739 if (!spec->autocfg.line_outs)
13740 return 0; /* can't find valid BIOS pin config */
13742 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13745 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13748 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13751 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13755 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13757 if (spec->autocfg.dig_out_pin)
13758 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13760 if (spec->kctls.list)
13761 add_mixer(spec, spec->kctls.list);
13763 add_verb(spec, alc861_auto_init_verbs);
13765 spec->num_mux_defs = 1;
13766 spec->input_mux = &spec->private_imux[0];
13768 spec->adc_nids = alc861_adc_nids;
13769 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13770 set_capture_mixer(spec);
13772 store_pin_configs(codec);
13776 /* additional initialization for auto-configuration model */
13777 static void alc861_auto_init(struct hda_codec *codec)
13779 struct alc_spec *spec = codec->spec;
13780 alc861_auto_init_multi_out(codec);
13781 alc861_auto_init_hp_out(codec);
13782 alc861_auto_init_analog_input(codec);
13783 if (spec->unsol_event)
13784 alc_inithook(codec);
13787 #ifdef CONFIG_SND_HDA_POWER_SAVE
13788 static struct hda_amp_list alc861_loopbacks[] = {
13789 { 0x15, HDA_INPUT, 0 },
13790 { 0x15, HDA_INPUT, 1 },
13791 { 0x15, HDA_INPUT, 2 },
13792 { 0x15, HDA_INPUT, 3 },
13799 * configuration and preset
13801 static const char *alc861_models[ALC861_MODEL_LAST] = {
13802 [ALC861_3ST] = "3stack",
13803 [ALC660_3ST] = "3stack-660",
13804 [ALC861_3ST_DIG] = "3stack-dig",
13805 [ALC861_6ST_DIG] = "6stack-dig",
13806 [ALC861_UNIWILL_M31] = "uniwill-m31",
13807 [ALC861_TOSHIBA] = "toshiba",
13808 [ALC861_ASUS] = "asus",
13809 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13810 [ALC861_AUTO] = "auto",
13813 static struct snd_pci_quirk alc861_cfg_tbl[] = {
13814 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13815 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13816 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13817 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13818 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13819 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13820 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13821 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13822 * Any other models that need this preset?
13824 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13825 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13826 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13827 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13828 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13829 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13830 /* FIXME: the below seems conflict */
13831 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13832 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13833 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13837 static struct alc_config_preset alc861_presets[] = {
13839 .mixers = { alc861_3ST_mixer },
13840 .init_verbs = { alc861_threestack_init_verbs },
13841 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13842 .dac_nids = alc861_dac_nids,
13843 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13844 .channel_mode = alc861_threestack_modes,
13846 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13847 .adc_nids = alc861_adc_nids,
13848 .input_mux = &alc861_capture_source,
13850 [ALC861_3ST_DIG] = {
13851 .mixers = { alc861_base_mixer },
13852 .init_verbs = { alc861_threestack_init_verbs },
13853 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13854 .dac_nids = alc861_dac_nids,
13855 .dig_out_nid = ALC861_DIGOUT_NID,
13856 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13857 .channel_mode = alc861_threestack_modes,
13859 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13860 .adc_nids = alc861_adc_nids,
13861 .input_mux = &alc861_capture_source,
13863 [ALC861_6ST_DIG] = {
13864 .mixers = { alc861_base_mixer },
13865 .init_verbs = { alc861_base_init_verbs },
13866 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13867 .dac_nids = alc861_dac_nids,
13868 .dig_out_nid = ALC861_DIGOUT_NID,
13869 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13870 .channel_mode = alc861_8ch_modes,
13871 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13872 .adc_nids = alc861_adc_nids,
13873 .input_mux = &alc861_capture_source,
13876 .mixers = { alc861_3ST_mixer },
13877 .init_verbs = { alc861_threestack_init_verbs },
13878 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13879 .dac_nids = alc660_dac_nids,
13880 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13881 .channel_mode = alc861_threestack_modes,
13883 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13884 .adc_nids = alc861_adc_nids,
13885 .input_mux = &alc861_capture_source,
13887 [ALC861_UNIWILL_M31] = {
13888 .mixers = { alc861_uniwill_m31_mixer },
13889 .init_verbs = { alc861_uniwill_m31_init_verbs },
13890 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13891 .dac_nids = alc861_dac_nids,
13892 .dig_out_nid = ALC861_DIGOUT_NID,
13893 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13894 .channel_mode = alc861_uniwill_m31_modes,
13896 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13897 .adc_nids = alc861_adc_nids,
13898 .input_mux = &alc861_capture_source,
13900 [ALC861_TOSHIBA] = {
13901 .mixers = { alc861_toshiba_mixer },
13902 .init_verbs = { alc861_base_init_verbs,
13903 alc861_toshiba_init_verbs },
13904 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13905 .dac_nids = alc861_dac_nids,
13906 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13907 .channel_mode = alc883_3ST_2ch_modes,
13908 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13909 .adc_nids = alc861_adc_nids,
13910 .input_mux = &alc861_capture_source,
13911 .unsol_event = alc861_toshiba_unsol_event,
13912 .init_hook = alc861_toshiba_automute,
13915 .mixers = { alc861_asus_mixer },
13916 .init_verbs = { alc861_asus_init_verbs },
13917 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13918 .dac_nids = alc861_dac_nids,
13919 .dig_out_nid = ALC861_DIGOUT_NID,
13920 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13921 .channel_mode = alc861_asus_modes,
13924 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13925 .adc_nids = alc861_adc_nids,
13926 .input_mux = &alc861_capture_source,
13928 [ALC861_ASUS_LAPTOP] = {
13929 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13930 .init_verbs = { alc861_asus_init_verbs,
13931 alc861_asus_laptop_init_verbs },
13932 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13933 .dac_nids = alc861_dac_nids,
13934 .dig_out_nid = ALC861_DIGOUT_NID,
13935 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13936 .channel_mode = alc883_3ST_2ch_modes,
13938 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13939 .adc_nids = alc861_adc_nids,
13940 .input_mux = &alc861_capture_source,
13945 static int patch_alc861(struct hda_codec *codec)
13947 struct alc_spec *spec;
13951 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13955 codec->spec = spec;
13957 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13961 if (board_config < 0) {
13962 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13963 "trying auto-probe from BIOS...\n");
13964 board_config = ALC861_AUTO;
13967 if (board_config == ALC861_AUTO) {
13968 /* automatic parse from the BIOS config */
13969 err = alc861_parse_auto_config(codec);
13975 "hda_codec: Cannot set up configuration "
13976 "from BIOS. Using base mode...\n");
13977 board_config = ALC861_3ST_DIG;
13981 if (board_config != ALC861_AUTO)
13982 setup_preset(spec, &alc861_presets[board_config]);
13984 spec->stream_name_analog = "ALC861 Analog";
13985 spec->stream_analog_playback = &alc861_pcm_analog_playback;
13986 spec->stream_analog_capture = &alc861_pcm_analog_capture;
13988 spec->stream_name_digital = "ALC861 Digital";
13989 spec->stream_digital_playback = &alc861_pcm_digital_playback;
13990 spec->stream_digital_capture = &alc861_pcm_digital_capture;
13992 spec->vmaster_nid = 0x03;
13994 codec->patch_ops = alc_patch_ops;
13995 if (board_config == ALC861_AUTO)
13996 spec->init_hook = alc861_auto_init;
13997 #ifdef CONFIG_SND_HDA_POWER_SAVE
13998 if (!spec->loopback.amplist)
13999 spec->loopback.amplist = alc861_loopbacks;
14001 codec->proc_widget_hook = print_realtek_coef;
14007 * ALC861-VD support
14011 * In addition, an independent DAC
14013 #define ALC861VD_DIGOUT_NID 0x06
14015 static hda_nid_t alc861vd_dac_nids[4] = {
14016 /* front, surr, clfe, side surr */
14017 0x02, 0x03, 0x04, 0x05
14020 /* dac_nids for ALC660vd are in a different order - according to
14021 * Realtek's driver.
14022 * This should probably tesult in a different mixer for 6stack models
14023 * of ALC660vd codecs, but for now there is only 3stack mixer
14024 * - and it is the same as in 861vd.
14025 * adc_nids in ALC660vd are (is) the same as in 861vd
14027 static hda_nid_t alc660vd_dac_nids[3] = {
14028 /* front, rear, clfe, rear_surr */
14032 static hda_nid_t alc861vd_adc_nids[1] = {
14037 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14040 /* FIXME: should be a matrix-type input source selection */
14041 static struct hda_input_mux alc861vd_capture_source = {
14045 { "Front Mic", 0x1 },
14051 static struct hda_input_mux alc861vd_dallas_capture_source = {
14054 { "Ext Mic", 0x0 },
14055 { "Int Mic", 0x1 },
14059 static struct hda_input_mux alc861vd_hp_capture_source = {
14062 { "Front Mic", 0x0 },
14063 { "ATAPI Mic", 0x1 },
14070 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14077 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14078 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14079 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14080 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14081 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14088 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14089 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14090 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14091 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14092 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14096 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14097 { 6, alc861vd_6stack_ch6_init },
14098 { 8, alc861vd_6stack_ch8_init },
14101 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14103 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14104 .name = "Channel Mode",
14105 .info = alc_ch_mode_info,
14106 .get = alc_ch_mode_get,
14107 .put = alc_ch_mode_put,
14112 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14113 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14115 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14116 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14117 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14119 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14120 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14122 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14124 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14126 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14127 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14129 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14130 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14132 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14134 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14135 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14136 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14138 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14139 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14140 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14142 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14143 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14145 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14146 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14148 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14149 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14154 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14155 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14156 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14158 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14160 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14161 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14162 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14164 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14165 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14166 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14168 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14169 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14171 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14172 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14174 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14175 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14180 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14181 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14182 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14183 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14185 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14187 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14188 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14189 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14191 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14192 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14193 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14195 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14196 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14201 /* Pin assignment: Speaker=0x14, HP = 0x15,
14202 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14204 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14205 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14206 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14207 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14208 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14209 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14210 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14211 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14212 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14213 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14214 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14215 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
14216 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
14220 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14221 * Front Mic=0x18, ATAPI Mic = 0x19,
14223 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14224 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14225 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14226 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14227 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14228 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14229 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14230 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14231 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14237 * generic initialization of ADC, input mixers and output mixers
14239 static struct hda_verb alc861vd_volume_init_verbs[] = {
14241 * Unmute ADC0 and set the default input to mic-in
14243 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14246 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14247 * the analog-loopback mixer widget
14249 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14252 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14253 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14254 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14256 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14257 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14258 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14259 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14260 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14263 * Set up output mixers (0x02 - 0x05)
14265 /* set vol=0 to output mixers */
14266 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14267 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14268 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14269 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14271 /* set up input amps for analog loopback */
14272 /* Amp Indices: DAC = 0, mixer = 1 */
14273 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14274 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14275 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14276 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14277 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14278 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14279 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14280 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14286 * 3-stack pin configuration:
14287 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14289 static struct hda_verb alc861vd_3stack_init_verbs[] = {
14291 * Set pin mode and muting
14293 /* set front pin widgets 0x14 for output */
14294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14295 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14296 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14298 /* Mic (rear) pin: input vref at 80% */
14299 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14300 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14301 /* Front Mic pin: input vref at 80% */
14302 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14303 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14304 /* Line In pin: input */
14305 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14306 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14307 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14308 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14309 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14310 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14311 /* CD pin widget for input */
14312 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14318 * 6-stack pin configuration:
14320 static struct hda_verb alc861vd_6stack_init_verbs[] = {
14322 * Set pin mode and muting
14324 /* set front pin widgets 0x14 for output */
14325 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14326 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14327 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14329 /* Rear Pin: output 1 (0x0d) */
14330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14333 /* CLFE Pin: output 2 (0x0e) */
14334 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14335 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14336 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14337 /* Side Pin: output 3 (0x0f) */
14338 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14339 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14340 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14342 /* Mic (rear) pin: input vref at 80% */
14343 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14344 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14345 /* Front Mic pin: input vref at 80% */
14346 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14347 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14348 /* Line In pin: input */
14349 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14350 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14351 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14352 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14353 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14354 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14355 /* CD pin widget for input */
14356 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14361 static struct hda_verb alc861vd_eapd_verbs[] = {
14362 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14366 static struct hda_verb alc660vd_eapd_verbs[] = {
14367 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14368 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14372 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14373 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14374 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14375 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14376 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14377 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14381 /* toggle speaker-output according to the hp-jack state */
14382 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
14384 unsigned int present;
14385 unsigned char bits;
14387 present = snd_hda_codec_read(codec, 0x1b, 0,
14388 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14389 bits = present ? HDA_AMP_MUTE : 0;
14390 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14391 HDA_AMP_MUTE, bits);
14394 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14396 unsigned int present;
14397 unsigned char bits;
14399 present = snd_hda_codec_read(codec, 0x18, 0,
14400 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14401 bits = present ? HDA_AMP_MUTE : 0;
14402 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14403 HDA_AMP_MUTE, bits);
14406 static void alc861vd_lenovo_automute(struct hda_codec *codec)
14408 alc861vd_lenovo_hp_automute(codec);
14409 alc861vd_lenovo_mic_automute(codec);
14412 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14415 switch (res >> 26) {
14416 case ALC880_HP_EVENT:
14417 alc861vd_lenovo_hp_automute(codec);
14419 case ALC880_MIC_EVENT:
14420 alc861vd_lenovo_mic_automute(codec);
14425 static struct hda_verb alc861vd_dallas_verbs[] = {
14426 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14427 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14428 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14429 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14431 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14432 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14433 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14434 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14435 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14436 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14437 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14438 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14440 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14441 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14442 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14443 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14444 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14445 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14446 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14447 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14449 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14450 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14451 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14452 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14453 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14454 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14455 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14456 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14458 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14459 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14460 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14461 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14463 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14464 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14465 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14470 /* toggle speaker-output according to the hp-jack state */
14471 static void alc861vd_dallas_automute(struct hda_codec *codec)
14473 unsigned int present;
14475 present = snd_hda_codec_read(codec, 0x15, 0,
14476 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14477 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14478 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14481 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14483 if ((res >> 26) == ALC880_HP_EVENT)
14484 alc861vd_dallas_automute(codec);
14487 #ifdef CONFIG_SND_HDA_POWER_SAVE
14488 #define alc861vd_loopbacks alc880_loopbacks
14491 /* pcm configuration: identiacal with ALC880 */
14492 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14493 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14494 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14495 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14498 * configuration and preset
14500 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14501 [ALC660VD_3ST] = "3stack-660",
14502 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14503 [ALC660VD_ASUS_V1S] = "asus-v1s",
14504 [ALC861VD_3ST] = "3stack",
14505 [ALC861VD_3ST_DIG] = "3stack-digout",
14506 [ALC861VD_6ST_DIG] = "6stack-digout",
14507 [ALC861VD_LENOVO] = "lenovo",
14508 [ALC861VD_DALLAS] = "dallas",
14509 [ALC861VD_HP] = "hp",
14510 [ALC861VD_AUTO] = "auto",
14513 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14514 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14515 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14516 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14517 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14518 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14519 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14520 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14521 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14522 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14523 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14524 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14525 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14526 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14527 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
14528 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
14529 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
14530 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14534 static struct alc_config_preset alc861vd_presets[] = {
14536 .mixers = { alc861vd_3st_mixer },
14537 .init_verbs = { alc861vd_volume_init_verbs,
14538 alc861vd_3stack_init_verbs },
14539 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14540 .dac_nids = alc660vd_dac_nids,
14541 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14542 .channel_mode = alc861vd_3stack_2ch_modes,
14543 .input_mux = &alc861vd_capture_source,
14545 [ALC660VD_3ST_DIG] = {
14546 .mixers = { alc861vd_3st_mixer },
14547 .init_verbs = { alc861vd_volume_init_verbs,
14548 alc861vd_3stack_init_verbs },
14549 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14550 .dac_nids = alc660vd_dac_nids,
14551 .dig_out_nid = ALC861VD_DIGOUT_NID,
14552 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14553 .channel_mode = alc861vd_3stack_2ch_modes,
14554 .input_mux = &alc861vd_capture_source,
14557 .mixers = { alc861vd_3st_mixer },
14558 .init_verbs = { alc861vd_volume_init_verbs,
14559 alc861vd_3stack_init_verbs },
14560 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14561 .dac_nids = alc861vd_dac_nids,
14562 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14563 .channel_mode = alc861vd_3stack_2ch_modes,
14564 .input_mux = &alc861vd_capture_source,
14566 [ALC861VD_3ST_DIG] = {
14567 .mixers = { alc861vd_3st_mixer },
14568 .init_verbs = { alc861vd_volume_init_verbs,
14569 alc861vd_3stack_init_verbs },
14570 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14571 .dac_nids = alc861vd_dac_nids,
14572 .dig_out_nid = ALC861VD_DIGOUT_NID,
14573 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14574 .channel_mode = alc861vd_3stack_2ch_modes,
14575 .input_mux = &alc861vd_capture_source,
14577 [ALC861VD_6ST_DIG] = {
14578 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14579 .init_verbs = { alc861vd_volume_init_verbs,
14580 alc861vd_6stack_init_verbs },
14581 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14582 .dac_nids = alc861vd_dac_nids,
14583 .dig_out_nid = ALC861VD_DIGOUT_NID,
14584 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14585 .channel_mode = alc861vd_6stack_modes,
14586 .input_mux = &alc861vd_capture_source,
14588 [ALC861VD_LENOVO] = {
14589 .mixers = { alc861vd_lenovo_mixer },
14590 .init_verbs = { alc861vd_volume_init_verbs,
14591 alc861vd_3stack_init_verbs,
14592 alc861vd_eapd_verbs,
14593 alc861vd_lenovo_unsol_verbs },
14594 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14595 .dac_nids = alc660vd_dac_nids,
14596 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14597 .channel_mode = alc861vd_3stack_2ch_modes,
14598 .input_mux = &alc861vd_capture_source,
14599 .unsol_event = alc861vd_lenovo_unsol_event,
14600 .init_hook = alc861vd_lenovo_automute,
14602 [ALC861VD_DALLAS] = {
14603 .mixers = { alc861vd_dallas_mixer },
14604 .init_verbs = { alc861vd_dallas_verbs },
14605 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14606 .dac_nids = alc861vd_dac_nids,
14607 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14608 .channel_mode = alc861vd_3stack_2ch_modes,
14609 .input_mux = &alc861vd_dallas_capture_source,
14610 .unsol_event = alc861vd_dallas_unsol_event,
14611 .init_hook = alc861vd_dallas_automute,
14614 .mixers = { alc861vd_hp_mixer },
14615 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14616 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14617 .dac_nids = alc861vd_dac_nids,
14618 .dig_out_nid = ALC861VD_DIGOUT_NID,
14619 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14620 .channel_mode = alc861vd_3stack_2ch_modes,
14621 .input_mux = &alc861vd_hp_capture_source,
14622 .unsol_event = alc861vd_dallas_unsol_event,
14623 .init_hook = alc861vd_dallas_automute,
14625 [ALC660VD_ASUS_V1S] = {
14626 .mixers = { alc861vd_lenovo_mixer },
14627 .init_verbs = { alc861vd_volume_init_verbs,
14628 alc861vd_3stack_init_verbs,
14629 alc861vd_eapd_verbs,
14630 alc861vd_lenovo_unsol_verbs },
14631 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14632 .dac_nids = alc660vd_dac_nids,
14633 .dig_out_nid = ALC861VD_DIGOUT_NID,
14634 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14635 .channel_mode = alc861vd_3stack_2ch_modes,
14636 .input_mux = &alc861vd_capture_source,
14637 .unsol_event = alc861vd_lenovo_unsol_event,
14638 .init_hook = alc861vd_lenovo_automute,
14643 * BIOS auto configuration
14645 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14646 hda_nid_t nid, int pin_type, int dac_idx)
14648 alc_set_pin_output(codec, nid, pin_type);
14651 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14653 struct alc_spec *spec = codec->spec;
14656 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14657 for (i = 0; i <= HDA_SIDE; i++) {
14658 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14659 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14661 alc861vd_auto_set_output_and_unmute(codec, nid,
14667 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14669 struct alc_spec *spec = codec->spec;
14672 pin = spec->autocfg.hp_pins[0];
14673 if (pin) /* connect to front and use dac 0 */
14674 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14675 pin = spec->autocfg.speaker_pins[0];
14677 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14680 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14681 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14683 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14685 struct alc_spec *spec = codec->spec;
14688 for (i = 0; i < AUTO_PIN_LAST; i++) {
14689 hda_nid_t nid = spec->autocfg.input_pins[i];
14690 if (alc861vd_is_input_pin(nid)) {
14691 snd_hda_codec_write(codec, nid, 0,
14692 AC_VERB_SET_PIN_WIDGET_CONTROL,
14693 i <= AUTO_PIN_FRONT_MIC ?
14694 PIN_VREF80 : PIN_IN);
14695 if (nid != ALC861VD_PIN_CD_NID)
14696 snd_hda_codec_write(codec, nid, 0,
14697 AC_VERB_SET_AMP_GAIN_MUTE,
14703 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14705 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14706 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14708 /* add playback controls from the parsed DAC table */
14709 /* Based on ALC880 version. But ALC861VD has separate,
14710 * different NIDs for mute/unmute switch and volume control */
14711 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14712 const struct auto_pin_cfg *cfg)
14715 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14716 hda_nid_t nid_v, nid_s;
14719 for (i = 0; i < cfg->line_outs; i++) {
14720 if (!spec->multiout.dac_nids[i])
14722 nid_v = alc861vd_idx_to_mixer_vol(
14724 spec->multiout.dac_nids[i]));
14725 nid_s = alc861vd_idx_to_mixer_switch(
14727 spec->multiout.dac_nids[i]));
14731 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14732 "Center Playback Volume",
14733 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14737 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14738 "LFE Playback Volume",
14739 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14743 err = add_control(spec, ALC_CTL_BIND_MUTE,
14744 "Center Playback Switch",
14745 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14749 err = add_control(spec, ALC_CTL_BIND_MUTE,
14750 "LFE Playback Switch",
14751 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14756 sprintf(name, "%s Playback Volume", chname[i]);
14757 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14758 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14762 sprintf(name, "%s Playback Switch", chname[i]);
14763 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14764 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14773 /* add playback controls for speaker and HP outputs */
14774 /* Based on ALC880 version. But ALC861VD has separate,
14775 * different NIDs for mute/unmute switch and volume control */
14776 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14777 hda_nid_t pin, const char *pfx)
14779 hda_nid_t nid_v, nid_s;
14786 if (alc880_is_fixed_pin(pin)) {
14787 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14788 /* specify the DAC as the extra output */
14789 if (!spec->multiout.hp_nid)
14790 spec->multiout.hp_nid = nid_v;
14792 spec->multiout.extra_out_nid[0] = nid_v;
14793 /* control HP volume/switch on the output mixer amp */
14794 nid_v = alc861vd_idx_to_mixer_vol(
14795 alc880_fixed_pin_idx(pin));
14796 nid_s = alc861vd_idx_to_mixer_switch(
14797 alc880_fixed_pin_idx(pin));
14799 sprintf(name, "%s Playback Volume", pfx);
14800 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14801 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14804 sprintf(name, "%s Playback Switch", pfx);
14805 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14806 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14809 } else if (alc880_is_multi_pin(pin)) {
14810 /* set manual connection */
14811 /* we have only a switch on HP-out PIN */
14812 sprintf(name, "%s Playback Switch", pfx);
14813 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14814 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14821 /* parse the BIOS configuration and set up the alc_spec
14822 * return 1 if successful, 0 if the proper config is not found,
14823 * or a negative error code
14824 * Based on ALC880 version - had to change it to override
14825 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14826 static int alc861vd_parse_auto_config(struct hda_codec *codec)
14828 struct alc_spec *spec = codec->spec;
14830 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14832 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14836 if (!spec->autocfg.line_outs)
14837 return 0; /* can't find valid BIOS pin config */
14839 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14842 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14845 err = alc861vd_auto_create_extra_out(spec,
14846 spec->autocfg.speaker_pins[0],
14850 err = alc861vd_auto_create_extra_out(spec,
14851 spec->autocfg.hp_pins[0],
14855 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14859 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14861 if (spec->autocfg.dig_out_pin)
14862 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14864 if (spec->kctls.list)
14865 add_mixer(spec, spec->kctls.list);
14867 add_verb(spec, alc861vd_volume_init_verbs);
14869 spec->num_mux_defs = 1;
14870 spec->input_mux = &spec->private_imux[0];
14872 err = alc_auto_add_mic_boost(codec);
14876 store_pin_configs(codec);
14880 /* additional initialization for auto-configuration model */
14881 static void alc861vd_auto_init(struct hda_codec *codec)
14883 struct alc_spec *spec = codec->spec;
14884 alc861vd_auto_init_multi_out(codec);
14885 alc861vd_auto_init_hp_out(codec);
14886 alc861vd_auto_init_analog_input(codec);
14887 alc861vd_auto_init_input_src(codec);
14888 if (spec->unsol_event)
14889 alc_inithook(codec);
14892 static int patch_alc861vd(struct hda_codec *codec)
14894 struct alc_spec *spec;
14895 int err, board_config;
14897 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14901 codec->spec = spec;
14903 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14907 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14908 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14909 "ALC861VD, trying auto-probe from BIOS...\n");
14910 board_config = ALC861VD_AUTO;
14913 if (board_config == ALC861VD_AUTO) {
14914 /* automatic parse from the BIOS config */
14915 err = alc861vd_parse_auto_config(codec);
14921 "hda_codec: Cannot set up configuration "
14922 "from BIOS. Using base mode...\n");
14923 board_config = ALC861VD_3ST;
14927 if (board_config != ALC861VD_AUTO)
14928 setup_preset(spec, &alc861vd_presets[board_config]);
14930 if (codec->vendor_id == 0x10ec0660) {
14931 spec->stream_name_analog = "ALC660-VD Analog";
14932 spec->stream_name_digital = "ALC660-VD Digital";
14933 /* always turn on EAPD */
14934 add_verb(spec, alc660vd_eapd_verbs);
14936 spec->stream_name_analog = "ALC861VD Analog";
14937 spec->stream_name_digital = "ALC861VD Digital";
14940 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14941 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14943 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14944 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14946 spec->adc_nids = alc861vd_adc_nids;
14947 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14948 spec->capsrc_nids = alc861vd_capsrc_nids;
14949 spec->capture_style = CAPT_MIX;
14951 set_capture_mixer(spec);
14953 spec->vmaster_nid = 0x02;
14955 codec->patch_ops = alc_patch_ops;
14957 if (board_config == ALC861VD_AUTO)
14958 spec->init_hook = alc861vd_auto_init;
14959 #ifdef CONFIG_SND_HDA_POWER_SAVE
14960 if (!spec->loopback.amplist)
14961 spec->loopback.amplist = alc861vd_loopbacks;
14963 codec->proc_widget_hook = print_realtek_coef;
14971 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14972 * configuration. Each pin widget can choose any input DACs and a mixer.
14973 * Each ADC is connected from a mixer of all inputs. This makes possible
14974 * 6-channel independent captures.
14976 * In addition, an independent DAC for the multi-playback (not used in this
14979 #define ALC662_DIGOUT_NID 0x06
14980 #define ALC662_DIGIN_NID 0x0a
14982 static hda_nid_t alc662_dac_nids[4] = {
14983 /* front, rear, clfe, rear_surr */
14987 static hda_nid_t alc662_adc_nids[1] = {
14992 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14995 /* FIXME: should be a matrix-type input source selection */
14996 static struct hda_input_mux alc662_capture_source = {
15000 { "Front Mic", 0x1 },
15006 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15014 static struct hda_input_mux alc662_eeepc_capture_source = {
15022 static struct hda_input_mux alc663_capture_source = {
15026 { "Front Mic", 0x1 },
15031 static struct hda_input_mux alc663_m51va_capture_source = {
15034 { "Ext-Mic", 0x0 },
15042 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15049 static struct hda_verb alc662_3ST_ch2_init[] = {
15050 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15051 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15052 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15053 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15060 static struct hda_verb alc662_3ST_ch6_init[] = {
15061 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15062 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15063 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15064 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15065 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15066 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15070 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15071 { 2, alc662_3ST_ch2_init },
15072 { 6, alc662_3ST_ch6_init },
15078 static struct hda_verb alc662_sixstack_ch6_init[] = {
15079 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15080 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15081 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15088 static struct hda_verb alc662_sixstack_ch8_init[] = {
15089 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15090 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15091 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15095 static struct hda_channel_mode alc662_5stack_modes[2] = {
15096 { 2, alc662_sixstack_ch6_init },
15097 { 6, alc662_sixstack_ch8_init },
15100 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15101 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15104 static struct snd_kcontrol_new alc662_base_mixer[] = {
15105 /* output mixer control */
15106 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15107 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15108 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15109 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15110 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15111 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15112 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15113 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15114 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15116 /*Input mixer control */
15117 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15118 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15119 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15120 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15121 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15122 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15123 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15124 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15128 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15129 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15130 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15131 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15132 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15133 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15134 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15135 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15136 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15137 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15138 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15139 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15140 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
15141 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
15145 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15146 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15147 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15148 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15149 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15150 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15151 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15152 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15153 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15154 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15155 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15156 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15157 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15158 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15159 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15160 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15161 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15162 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15163 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
15164 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
15168 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15169 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15170 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15171 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15172 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15173 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15174 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15175 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15177 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15181 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15182 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15184 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15185 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15187 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15188 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15189 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15191 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15192 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15193 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15197 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15198 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15199 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15200 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15201 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
15202 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15203 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15204 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
15205 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
15206 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15207 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15208 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15209 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15210 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15211 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15215 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15216 .ops = &snd_hda_bind_vol,
15218 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15219 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15224 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15225 .ops = &snd_hda_bind_sw,
15227 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15228 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15233 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15234 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15235 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15236 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15241 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15242 .ops = &snd_hda_bind_sw,
15244 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15245 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15246 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15251 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15252 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15253 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15254 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15255 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15256 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15257 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15262 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15263 .ops = &snd_hda_bind_sw,
15265 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15266 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15267 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15272 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15273 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15274 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15275 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15276 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15277 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15278 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15282 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15283 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15284 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15285 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15286 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15287 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15288 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15289 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15293 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15294 .ops = &snd_hda_bind_vol,
15296 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15297 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15302 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15303 .ops = &snd_hda_bind_sw,
15305 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15306 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15311 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15312 HDA_BIND_VOL("Master Playback Volume",
15313 &alc663_asus_two_bind_master_vol),
15314 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15315 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15316 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15317 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15318 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15322 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15323 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15324 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15325 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15326 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15327 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15328 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15332 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15333 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15334 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15335 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15336 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15337 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15339 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15340 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15341 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15342 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15346 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15347 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15348 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15349 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15352 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15353 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15354 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15355 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15356 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15360 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15362 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15363 .name = "Channel Mode",
15364 .info = alc_ch_mode_info,
15365 .get = alc_ch_mode_get,
15366 .put = alc_ch_mode_put,
15371 static struct hda_verb alc662_init_verbs[] = {
15372 /* ADC: mute amp left and right */
15373 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15374 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15375 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15377 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15378 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15379 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15380 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15381 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15383 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15384 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15385 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15386 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15387 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15388 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15390 /* Front Pin: output 0 (0x0c) */
15391 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15392 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15394 /* Rear Pin: output 1 (0x0d) */
15395 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15396 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15398 /* CLFE Pin: output 2 (0x0e) */
15399 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15400 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15402 /* Mic (rear) pin: input vref at 80% */
15403 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15404 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15405 /* Front Mic pin: input vref at 80% */
15406 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15407 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15408 /* Line In pin: input */
15409 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15410 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15411 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15412 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15413 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15414 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15415 /* CD pin widget for input */
15416 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15418 /* FIXME: use matrix-type input source selection */
15419 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15421 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15422 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15423 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15424 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
15426 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15427 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15428 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15429 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
15431 /* always trun on EAPD */
15432 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15433 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15438 static struct hda_verb alc662_sue_init_verbs[] = {
15439 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15440 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15444 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15445 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15446 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15450 /* Set Unsolicited Event*/
15451 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15452 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15453 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15458 * generic initialization of ADC, input mixers and output mixers
15460 static struct hda_verb alc662_auto_init_verbs[] = {
15462 * Unmute ADC and set the default input to mic-in
15464 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15465 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15467 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15469 * Note: PASD motherboards uses the Line In 2 as the input for front
15470 * panel mic (mic 2)
15472 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15473 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15474 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15475 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15476 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15477 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15480 * Set up output mixers (0x0c - 0x0f)
15482 /* set vol=0 to output mixers */
15483 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15484 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15485 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15487 /* set up input amps for analog loopback */
15488 /* Amp Indices: DAC = 0, mixer = 1 */
15489 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15490 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15491 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15492 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15493 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15494 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15497 /* FIXME: use matrix-type input source selection */
15498 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15500 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15501 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15505 /* additional verbs for ALC663 */
15506 static struct hda_verb alc663_auto_init_verbs[] = {
15507 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15508 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15512 static struct hda_verb alc663_m51va_init_verbs[] = {
15513 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15514 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15515 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15516 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15517 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15518 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15519 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15520 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15521 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15525 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15526 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15527 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15528 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15529 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15530 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15531 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15532 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15536 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15537 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15538 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15539 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15540 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15541 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15542 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15543 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15544 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15548 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15549 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15550 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15551 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15552 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15553 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15554 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15555 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15559 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15560 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15561 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15562 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15563 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15564 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15565 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15566 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15567 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15568 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15569 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15570 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15571 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15575 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15576 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15577 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15578 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15579 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15580 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15581 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15582 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15583 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15584 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15585 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15586 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15587 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15591 static struct hda_verb alc663_g71v_init_verbs[] = {
15592 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15593 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15594 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15596 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15597 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15598 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15600 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15601 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15602 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15606 static struct hda_verb alc663_g50v_init_verbs[] = {
15607 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15608 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15609 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15611 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15612 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15616 static struct hda_verb alc662_ecs_init_verbs[] = {
15617 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15619 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15620 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15624 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15625 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15626 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15630 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15632 unsigned int present;
15633 unsigned char bits;
15635 present = snd_hda_codec_read(codec, 0x14, 0,
15636 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15637 bits = present ? HDA_AMP_MUTE : 0;
15638 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15639 HDA_AMP_MUTE, bits);
15642 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15644 unsigned int present;
15645 unsigned char bits;
15647 present = snd_hda_codec_read(codec, 0x1b, 0,
15648 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15649 bits = present ? HDA_AMP_MUTE : 0;
15650 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15651 HDA_AMP_MUTE, bits);
15652 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15653 HDA_AMP_MUTE, bits);
15656 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15659 if ((res >> 26) == ALC880_HP_EVENT)
15660 alc662_lenovo_101e_all_automute(codec);
15661 if ((res >> 26) == ALC880_FRONT_EVENT)
15662 alc662_lenovo_101e_ispeaker_automute(codec);
15665 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15667 unsigned int present;
15669 present = snd_hda_codec_read(codec, 0x18, 0,
15670 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15671 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15672 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15673 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15674 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15675 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15676 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15677 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15678 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15681 /* unsolicited event for HP jack sensing */
15682 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15685 if ((res >> 26) == ALC880_HP_EVENT)
15686 alc262_hippo1_automute( codec );
15688 if ((res >> 26) == ALC880_MIC_EVENT)
15689 alc662_eeepc_mic_automute(codec);
15692 static void alc662_eeepc_inithook(struct hda_codec *codec)
15694 alc262_hippo1_automute( codec );
15695 alc662_eeepc_mic_automute(codec);
15698 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15701 unsigned int present;
15703 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15704 present = snd_hda_codec_read(codec, 0x14, 0,
15705 AC_VERB_GET_PIN_SENSE, 0);
15706 present = (present & 0x80000000) != 0;
15708 /* mute internal speaker */
15709 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15710 HDA_AMP_MUTE, HDA_AMP_MUTE);
15712 /* unmute internal speaker if necessary */
15713 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15714 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15715 HDA_AMP_MUTE, mute);
15719 /* unsolicited event for HP jack sensing */
15720 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15723 if ((res >> 26) == ALC880_HP_EVENT)
15724 alc662_eeepc_ep20_automute(codec);
15727 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15729 alc662_eeepc_ep20_automute(codec);
15732 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15734 unsigned int present;
15735 unsigned char bits;
15737 present = snd_hda_codec_read(codec, 0x21, 0,
15738 AC_VERB_GET_PIN_SENSE, 0)
15739 & AC_PINSENSE_PRESENCE;
15740 bits = present ? HDA_AMP_MUTE : 0;
15741 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15742 AMP_IN_MUTE(0), bits);
15743 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15744 AMP_IN_MUTE(0), bits);
15747 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15749 unsigned int present;
15750 unsigned char bits;
15752 present = snd_hda_codec_read(codec, 0x21, 0,
15753 AC_VERB_GET_PIN_SENSE, 0)
15754 & AC_PINSENSE_PRESENCE;
15755 bits = present ? HDA_AMP_MUTE : 0;
15756 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15757 AMP_IN_MUTE(0), bits);
15758 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15759 AMP_IN_MUTE(0), bits);
15760 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15761 AMP_IN_MUTE(0), bits);
15762 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15763 AMP_IN_MUTE(0), bits);
15766 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15768 unsigned int present;
15769 unsigned char bits;
15771 present = snd_hda_codec_read(codec, 0x15, 0,
15772 AC_VERB_GET_PIN_SENSE, 0)
15773 & AC_PINSENSE_PRESENCE;
15774 bits = present ? HDA_AMP_MUTE : 0;
15775 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15776 AMP_IN_MUTE(0), bits);
15777 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15778 AMP_IN_MUTE(0), bits);
15779 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15780 AMP_IN_MUTE(0), bits);
15781 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15782 AMP_IN_MUTE(0), bits);
15785 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15787 unsigned int present;
15788 unsigned char bits;
15790 present = snd_hda_codec_read(codec, 0x1b, 0,
15791 AC_VERB_GET_PIN_SENSE, 0)
15792 & AC_PINSENSE_PRESENCE;
15793 bits = present ? 0 : PIN_OUT;
15794 snd_hda_codec_write(codec, 0x14, 0,
15795 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15798 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15800 unsigned int present1, present2;
15802 present1 = snd_hda_codec_read(codec, 0x21, 0,
15803 AC_VERB_GET_PIN_SENSE, 0)
15804 & AC_PINSENSE_PRESENCE;
15805 present2 = snd_hda_codec_read(codec, 0x15, 0,
15806 AC_VERB_GET_PIN_SENSE, 0)
15807 & AC_PINSENSE_PRESENCE;
15809 if (present1 || present2) {
15810 snd_hda_codec_write_cache(codec, 0x14, 0,
15811 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15813 snd_hda_codec_write_cache(codec, 0x14, 0,
15814 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15818 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15820 unsigned int present1, present2;
15822 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15823 AC_VERB_GET_PIN_SENSE, 0)
15824 & AC_PINSENSE_PRESENCE;
15825 present2 = snd_hda_codec_read(codec, 0x15, 0,
15826 AC_VERB_GET_PIN_SENSE, 0)
15827 & AC_PINSENSE_PRESENCE;
15829 if (present1 || present2) {
15830 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15831 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15832 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15833 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15835 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15836 AMP_IN_MUTE(0), 0);
15837 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15838 AMP_IN_MUTE(0), 0);
15842 static void alc663_m51va_mic_automute(struct hda_codec *codec)
15844 unsigned int present;
15846 present = snd_hda_codec_read(codec, 0x18, 0,
15847 AC_VERB_GET_PIN_SENSE, 0)
15848 & AC_PINSENSE_PRESENCE;
15849 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15850 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15851 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15852 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15853 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15854 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15855 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15856 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15859 static void alc663_m51va_unsol_event(struct hda_codec *codec,
15862 switch (res >> 26) {
15863 case ALC880_HP_EVENT:
15864 alc663_m51va_speaker_automute(codec);
15866 case ALC880_MIC_EVENT:
15867 alc663_m51va_mic_automute(codec);
15872 static void alc663_m51va_inithook(struct hda_codec *codec)
15874 alc663_m51va_speaker_automute(codec);
15875 alc663_m51va_mic_automute(codec);
15878 /* ***************** Mode1 ******************************/
15879 static void alc663_mode1_unsol_event(struct hda_codec *codec,
15882 switch (res >> 26) {
15883 case ALC880_HP_EVENT:
15884 alc663_m51va_speaker_automute(codec);
15886 case ALC880_MIC_EVENT:
15887 alc662_eeepc_mic_automute(codec);
15892 static void alc663_mode1_inithook(struct hda_codec *codec)
15894 alc663_m51va_speaker_automute(codec);
15895 alc662_eeepc_mic_automute(codec);
15897 /* ***************** Mode2 ******************************/
15898 static void alc662_mode2_unsol_event(struct hda_codec *codec,
15901 switch (res >> 26) {
15902 case ALC880_HP_EVENT:
15903 alc662_f5z_speaker_automute(codec);
15905 case ALC880_MIC_EVENT:
15906 alc662_eeepc_mic_automute(codec);
15911 static void alc662_mode2_inithook(struct hda_codec *codec)
15913 alc662_f5z_speaker_automute(codec);
15914 alc662_eeepc_mic_automute(codec);
15916 /* ***************** Mode3 ******************************/
15917 static void alc663_mode3_unsol_event(struct hda_codec *codec,
15920 switch (res >> 26) {
15921 case ALC880_HP_EVENT:
15922 alc663_two_hp_m1_speaker_automute(codec);
15924 case ALC880_MIC_EVENT:
15925 alc662_eeepc_mic_automute(codec);
15930 static void alc663_mode3_inithook(struct hda_codec *codec)
15932 alc663_two_hp_m1_speaker_automute(codec);
15933 alc662_eeepc_mic_automute(codec);
15935 /* ***************** Mode4 ******************************/
15936 static void alc663_mode4_unsol_event(struct hda_codec *codec,
15939 switch (res >> 26) {
15940 case ALC880_HP_EVENT:
15941 alc663_21jd_two_speaker_automute(codec);
15943 case ALC880_MIC_EVENT:
15944 alc662_eeepc_mic_automute(codec);
15949 static void alc663_mode4_inithook(struct hda_codec *codec)
15951 alc663_21jd_two_speaker_automute(codec);
15952 alc662_eeepc_mic_automute(codec);
15954 /* ***************** Mode5 ******************************/
15955 static void alc663_mode5_unsol_event(struct hda_codec *codec,
15958 switch (res >> 26) {
15959 case ALC880_HP_EVENT:
15960 alc663_15jd_two_speaker_automute(codec);
15962 case ALC880_MIC_EVENT:
15963 alc662_eeepc_mic_automute(codec);
15968 static void alc663_mode5_inithook(struct hda_codec *codec)
15970 alc663_15jd_two_speaker_automute(codec);
15971 alc662_eeepc_mic_automute(codec);
15973 /* ***************** Mode6 ******************************/
15974 static void alc663_mode6_unsol_event(struct hda_codec *codec,
15977 switch (res >> 26) {
15978 case ALC880_HP_EVENT:
15979 alc663_two_hp_m2_speaker_automute(codec);
15981 case ALC880_MIC_EVENT:
15982 alc662_eeepc_mic_automute(codec);
15987 static void alc663_mode6_inithook(struct hda_codec *codec)
15989 alc663_two_hp_m2_speaker_automute(codec);
15990 alc662_eeepc_mic_automute(codec);
15993 static void alc663_g71v_hp_automute(struct hda_codec *codec)
15995 unsigned int present;
15996 unsigned char bits;
15998 present = snd_hda_codec_read(codec, 0x21, 0,
15999 AC_VERB_GET_PIN_SENSE, 0)
16000 & AC_PINSENSE_PRESENCE;
16001 bits = present ? HDA_AMP_MUTE : 0;
16002 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16003 HDA_AMP_MUTE, bits);
16004 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16005 HDA_AMP_MUTE, bits);
16008 static void alc663_g71v_front_automute(struct hda_codec *codec)
16010 unsigned int present;
16011 unsigned char bits;
16013 present = snd_hda_codec_read(codec, 0x15, 0,
16014 AC_VERB_GET_PIN_SENSE, 0)
16015 & AC_PINSENSE_PRESENCE;
16016 bits = present ? HDA_AMP_MUTE : 0;
16017 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16018 HDA_AMP_MUTE, bits);
16021 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16024 switch (res >> 26) {
16025 case ALC880_HP_EVENT:
16026 alc663_g71v_hp_automute(codec);
16028 case ALC880_FRONT_EVENT:
16029 alc663_g71v_front_automute(codec);
16031 case ALC880_MIC_EVENT:
16032 alc662_eeepc_mic_automute(codec);
16037 static void alc663_g71v_inithook(struct hda_codec *codec)
16039 alc663_g71v_front_automute(codec);
16040 alc663_g71v_hp_automute(codec);
16041 alc662_eeepc_mic_automute(codec);
16044 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16047 switch (res >> 26) {
16048 case ALC880_HP_EVENT:
16049 alc663_m51va_speaker_automute(codec);
16051 case ALC880_MIC_EVENT:
16052 alc662_eeepc_mic_automute(codec);
16057 static void alc663_g50v_inithook(struct hda_codec *codec)
16059 alc663_m51va_speaker_automute(codec);
16060 alc662_eeepc_mic_automute(codec);
16063 /* bind hp and internal speaker mute (with plug check) */
16064 static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
16065 struct snd_ctl_elem_value *ucontrol)
16067 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
16068 long *valp = ucontrol->value.integer.value;
16071 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
16073 valp[0] ? 0 : HDA_AMP_MUTE);
16074 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
16076 valp[1] ? 0 : HDA_AMP_MUTE);
16078 alc262_hippo1_automute(codec);
16082 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16083 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16085 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16086 .name = "Master Playback Switch",
16087 .info = snd_hda_mixer_amp_switch_info,
16088 .get = snd_hda_mixer_amp_switch_get,
16089 .put = alc662_ecs_master_sw_put,
16090 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16093 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16094 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16095 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16097 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16098 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16099 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16103 #ifdef CONFIG_SND_HDA_POWER_SAVE
16104 #define alc662_loopbacks alc880_loopbacks
16108 /* pcm configuration: identiacal with ALC880 */
16109 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16110 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16111 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16112 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16115 * configuration and preset
16117 static const char *alc662_models[ALC662_MODEL_LAST] = {
16118 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16119 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16120 [ALC662_3ST_6ch] = "3stack-6ch",
16121 [ALC662_5ST_DIG] = "6stack-dig",
16122 [ALC662_LENOVO_101E] = "lenovo-101e",
16123 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16124 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16125 [ALC662_ECS] = "ecs",
16126 [ALC663_ASUS_M51VA] = "m51va",
16127 [ALC663_ASUS_G71V] = "g71v",
16128 [ALC663_ASUS_H13] = "h13",
16129 [ALC663_ASUS_G50V] = "g50v",
16130 [ALC663_ASUS_MODE1] = "asus-mode1",
16131 [ALC662_ASUS_MODE2] = "asus-mode2",
16132 [ALC663_ASUS_MODE3] = "asus-mode3",
16133 [ALC663_ASUS_MODE4] = "asus-mode4",
16134 [ALC663_ASUS_MODE5] = "asus-mode5",
16135 [ALC663_ASUS_MODE6] = "asus-mode6",
16136 [ALC662_AUTO] = "auto",
16139 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16140 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16141 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16142 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16143 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16144 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16145 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16146 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
16147 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16148 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16149 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16150 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
16151 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16152 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16153 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16154 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16155 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16156 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16157 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16158 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16159 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16160 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16161 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16162 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16163 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16164 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16165 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16166 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16167 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16168 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16169 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16170 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16171 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16172 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16173 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16174 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16175 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16176 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16177 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16178 ALC662_3ST_6ch_DIG),
16179 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16180 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16181 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16182 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16183 ALC662_3ST_6ch_DIG),
16184 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16185 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16186 ALC662_3ST_6ch_DIG),
16187 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
16188 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
16189 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
16193 static struct alc_config_preset alc662_presets[] = {
16194 [ALC662_3ST_2ch_DIG] = {
16195 .mixers = { alc662_3ST_2ch_mixer },
16196 .init_verbs = { alc662_init_verbs },
16197 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16198 .dac_nids = alc662_dac_nids,
16199 .dig_out_nid = ALC662_DIGOUT_NID,
16200 .dig_in_nid = ALC662_DIGIN_NID,
16201 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16202 .channel_mode = alc662_3ST_2ch_modes,
16203 .input_mux = &alc662_capture_source,
16205 [ALC662_3ST_6ch_DIG] = {
16206 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16207 .init_verbs = { alc662_init_verbs },
16208 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16209 .dac_nids = alc662_dac_nids,
16210 .dig_out_nid = ALC662_DIGOUT_NID,
16211 .dig_in_nid = ALC662_DIGIN_NID,
16212 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16213 .channel_mode = alc662_3ST_6ch_modes,
16215 .input_mux = &alc662_capture_source,
16217 [ALC662_3ST_6ch] = {
16218 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16219 .init_verbs = { alc662_init_verbs },
16220 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16221 .dac_nids = alc662_dac_nids,
16222 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16223 .channel_mode = alc662_3ST_6ch_modes,
16225 .input_mux = &alc662_capture_source,
16227 [ALC662_5ST_DIG] = {
16228 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16229 .init_verbs = { alc662_init_verbs },
16230 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16231 .dac_nids = alc662_dac_nids,
16232 .dig_out_nid = ALC662_DIGOUT_NID,
16233 .dig_in_nid = ALC662_DIGIN_NID,
16234 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16235 .channel_mode = alc662_5stack_modes,
16236 .input_mux = &alc662_capture_source,
16238 [ALC662_LENOVO_101E] = {
16239 .mixers = { alc662_lenovo_101e_mixer },
16240 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16241 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16242 .dac_nids = alc662_dac_nids,
16243 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16244 .channel_mode = alc662_3ST_2ch_modes,
16245 .input_mux = &alc662_lenovo_101e_capture_source,
16246 .unsol_event = alc662_lenovo_101e_unsol_event,
16247 .init_hook = alc662_lenovo_101e_all_automute,
16249 [ALC662_ASUS_EEEPC_P701] = {
16250 .mixers = { alc662_eeepc_p701_mixer },
16251 .init_verbs = { alc662_init_verbs,
16252 alc662_eeepc_sue_init_verbs },
16253 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16254 .dac_nids = alc662_dac_nids,
16255 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16256 .channel_mode = alc662_3ST_2ch_modes,
16257 .input_mux = &alc662_eeepc_capture_source,
16258 .unsol_event = alc662_eeepc_unsol_event,
16259 .init_hook = alc662_eeepc_inithook,
16261 [ALC662_ASUS_EEEPC_EP20] = {
16262 .mixers = { alc662_eeepc_ep20_mixer,
16263 alc662_chmode_mixer },
16264 .init_verbs = { alc662_init_verbs,
16265 alc662_eeepc_ep20_sue_init_verbs },
16266 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16267 .dac_nids = alc662_dac_nids,
16268 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16269 .channel_mode = alc662_3ST_6ch_modes,
16270 .input_mux = &alc662_lenovo_101e_capture_source,
16271 .unsol_event = alc662_eeepc_ep20_unsol_event,
16272 .init_hook = alc662_eeepc_ep20_inithook,
16275 .mixers = { alc662_ecs_mixer },
16276 .init_verbs = { alc662_init_verbs,
16277 alc662_ecs_init_verbs },
16278 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16279 .dac_nids = alc662_dac_nids,
16280 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16281 .channel_mode = alc662_3ST_2ch_modes,
16282 .input_mux = &alc662_eeepc_capture_source,
16283 .unsol_event = alc662_eeepc_unsol_event,
16284 .init_hook = alc662_eeepc_inithook,
16286 [ALC663_ASUS_M51VA] = {
16287 .mixers = { alc663_m51va_mixer },
16288 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16289 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16290 .dac_nids = alc662_dac_nids,
16291 .dig_out_nid = ALC662_DIGOUT_NID,
16292 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16293 .channel_mode = alc662_3ST_2ch_modes,
16294 .input_mux = &alc663_m51va_capture_source,
16295 .unsol_event = alc663_m51va_unsol_event,
16296 .init_hook = alc663_m51va_inithook,
16298 [ALC663_ASUS_G71V] = {
16299 .mixers = { alc663_g71v_mixer },
16300 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16301 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16302 .dac_nids = alc662_dac_nids,
16303 .dig_out_nid = ALC662_DIGOUT_NID,
16304 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16305 .channel_mode = alc662_3ST_2ch_modes,
16306 .input_mux = &alc662_eeepc_capture_source,
16307 .unsol_event = alc663_g71v_unsol_event,
16308 .init_hook = alc663_g71v_inithook,
16310 [ALC663_ASUS_H13] = {
16311 .mixers = { alc663_m51va_mixer },
16312 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16313 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16314 .dac_nids = alc662_dac_nids,
16315 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16316 .channel_mode = alc662_3ST_2ch_modes,
16317 .input_mux = &alc663_m51va_capture_source,
16318 .unsol_event = alc663_m51va_unsol_event,
16319 .init_hook = alc663_m51va_inithook,
16321 [ALC663_ASUS_G50V] = {
16322 .mixers = { alc663_g50v_mixer },
16323 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16324 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16325 .dac_nids = alc662_dac_nids,
16326 .dig_out_nid = ALC662_DIGOUT_NID,
16327 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16328 .channel_mode = alc662_3ST_6ch_modes,
16329 .input_mux = &alc663_capture_source,
16330 .unsol_event = alc663_g50v_unsol_event,
16331 .init_hook = alc663_g50v_inithook,
16333 [ALC663_ASUS_MODE1] = {
16334 .mixers = { alc663_m51va_mixer },
16335 .cap_mixer = alc662_auto_capture_mixer,
16336 .init_verbs = { alc662_init_verbs,
16337 alc663_21jd_amic_init_verbs },
16338 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16340 .dac_nids = alc662_dac_nids,
16341 .dig_out_nid = ALC662_DIGOUT_NID,
16342 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16343 .channel_mode = alc662_3ST_2ch_modes,
16344 .input_mux = &alc662_eeepc_capture_source,
16345 .unsol_event = alc663_mode1_unsol_event,
16346 .init_hook = alc663_mode1_inithook,
16348 [ALC662_ASUS_MODE2] = {
16349 .mixers = { alc662_1bjd_mixer },
16350 .cap_mixer = alc662_auto_capture_mixer,
16351 .init_verbs = { alc662_init_verbs,
16352 alc662_1bjd_amic_init_verbs },
16353 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16354 .dac_nids = alc662_dac_nids,
16355 .dig_out_nid = ALC662_DIGOUT_NID,
16356 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16357 .channel_mode = alc662_3ST_2ch_modes,
16358 .input_mux = &alc662_eeepc_capture_source,
16359 .unsol_event = alc662_mode2_unsol_event,
16360 .init_hook = alc662_mode2_inithook,
16362 [ALC663_ASUS_MODE3] = {
16363 .mixers = { alc663_two_hp_m1_mixer },
16364 .cap_mixer = alc662_auto_capture_mixer,
16365 .init_verbs = { alc662_init_verbs,
16366 alc663_two_hp_amic_m1_init_verbs },
16367 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16369 .dac_nids = alc662_dac_nids,
16370 .dig_out_nid = ALC662_DIGOUT_NID,
16371 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16372 .channel_mode = alc662_3ST_2ch_modes,
16373 .input_mux = &alc662_eeepc_capture_source,
16374 .unsol_event = alc663_mode3_unsol_event,
16375 .init_hook = alc663_mode3_inithook,
16377 [ALC663_ASUS_MODE4] = {
16378 .mixers = { alc663_asus_21jd_clfe_mixer },
16379 .cap_mixer = alc662_auto_capture_mixer,
16380 .init_verbs = { alc662_init_verbs,
16381 alc663_21jd_amic_init_verbs},
16382 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16384 .dac_nids = alc662_dac_nids,
16385 .dig_out_nid = ALC662_DIGOUT_NID,
16386 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16387 .channel_mode = alc662_3ST_2ch_modes,
16388 .input_mux = &alc662_eeepc_capture_source,
16389 .unsol_event = alc663_mode4_unsol_event,
16390 .init_hook = alc663_mode4_inithook,
16392 [ALC663_ASUS_MODE5] = {
16393 .mixers = { alc663_asus_15jd_clfe_mixer },
16394 .cap_mixer = alc662_auto_capture_mixer,
16395 .init_verbs = { alc662_init_verbs,
16396 alc663_15jd_amic_init_verbs },
16397 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16399 .dac_nids = alc662_dac_nids,
16400 .dig_out_nid = ALC662_DIGOUT_NID,
16401 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16402 .channel_mode = alc662_3ST_2ch_modes,
16403 .input_mux = &alc662_eeepc_capture_source,
16404 .unsol_event = alc663_mode5_unsol_event,
16405 .init_hook = alc663_mode5_inithook,
16407 [ALC663_ASUS_MODE6] = {
16408 .mixers = { alc663_two_hp_m2_mixer },
16409 .cap_mixer = alc662_auto_capture_mixer,
16410 .init_verbs = { alc662_init_verbs,
16411 alc663_two_hp_amic_m2_init_verbs },
16412 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16414 .dac_nids = alc662_dac_nids,
16415 .dig_out_nid = ALC662_DIGOUT_NID,
16416 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16417 .channel_mode = alc662_3ST_2ch_modes,
16418 .input_mux = &alc662_eeepc_capture_source,
16419 .unsol_event = alc663_mode6_unsol_event,
16420 .init_hook = alc663_mode6_inithook,
16426 * BIOS auto configuration
16429 /* add playback controls from the parsed DAC table */
16430 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16431 const struct auto_pin_cfg *cfg)
16434 static const char *chname[4] = {
16435 "Front", "Surround", NULL /*CLFE*/, "Side"
16440 for (i = 0; i < cfg->line_outs; i++) {
16441 if (!spec->multiout.dac_nids[i])
16443 nid = alc880_idx_to_dac(i);
16446 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16447 "Center Playback Volume",
16448 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16452 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16453 "LFE Playback Volume",
16454 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16458 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16459 "Center Playback Switch",
16460 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16464 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16465 "LFE Playback Switch",
16466 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16471 sprintf(name, "%s Playback Volume", chname[i]);
16472 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16473 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16477 sprintf(name, "%s Playback Switch", chname[i]);
16478 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16479 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16488 /* add playback controls for speaker and HP outputs */
16489 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16500 /* ALC663 has a mono output pin on 0x17 */
16501 sprintf(name, "%s Playback Switch", pfx);
16502 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16503 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16507 if (alc880_is_fixed_pin(pin)) {
16508 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16509 /* printk("DAC nid=%x\n",nid); */
16510 /* specify the DAC as the extra output */
16511 if (!spec->multiout.hp_nid)
16512 spec->multiout.hp_nid = nid;
16514 spec->multiout.extra_out_nid[0] = nid;
16515 /* control HP volume/switch on the output mixer amp */
16516 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16517 sprintf(name, "%s Playback Volume", pfx);
16518 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16519 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16522 sprintf(name, "%s Playback Switch", pfx);
16523 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16524 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16527 } else if (alc880_is_multi_pin(pin)) {
16528 /* set manual connection */
16529 /* we have only a switch on HP-out PIN */
16530 sprintf(name, "%s Playback Switch", pfx);
16531 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16532 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16539 /* create playback/capture controls for input pins */
16540 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16541 const struct auto_pin_cfg *cfg)
16543 struct hda_input_mux *imux = &spec->private_imux[0];
16546 for (i = 0; i < AUTO_PIN_LAST; i++) {
16547 if (alc880_is_input_pin(cfg->input_pins[i])) {
16548 idx = alc880_input_pin_idx(cfg->input_pins[i]);
16549 err = new_analog_input(spec, cfg->input_pins[i],
16550 auto_pin_cfg_labels[i],
16554 imux->items[imux->num_items].label =
16555 auto_pin_cfg_labels[i];
16556 imux->items[imux->num_items].index =
16557 alc880_input_pin_idx(cfg->input_pins[i]);
16564 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16565 hda_nid_t nid, int pin_type,
16568 alc_set_pin_output(codec, nid, pin_type);
16569 /* need the manual connection? */
16570 if (alc880_is_multi_pin(nid)) {
16571 struct alc_spec *spec = codec->spec;
16572 int idx = alc880_multi_pin_idx(nid);
16573 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16574 AC_VERB_SET_CONNECT_SEL,
16575 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16579 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16581 struct alc_spec *spec = codec->spec;
16584 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16585 for (i = 0; i <= HDA_SIDE; i++) {
16586 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16587 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16589 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16594 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16596 struct alc_spec *spec = codec->spec;
16599 pin = spec->autocfg.hp_pins[0];
16600 if (pin) /* connect to front */
16602 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16603 pin = spec->autocfg.speaker_pins[0];
16605 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16608 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
16609 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16611 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16613 struct alc_spec *spec = codec->spec;
16616 for (i = 0; i < AUTO_PIN_LAST; i++) {
16617 hda_nid_t nid = spec->autocfg.input_pins[i];
16618 if (alc662_is_input_pin(nid)) {
16619 snd_hda_codec_write(codec, nid, 0,
16620 AC_VERB_SET_PIN_WIDGET_CONTROL,
16621 (i <= AUTO_PIN_FRONT_MIC ?
16622 PIN_VREF80 : PIN_IN));
16623 if (nid != ALC662_PIN_CD_NID)
16624 snd_hda_codec_write(codec, nid, 0,
16625 AC_VERB_SET_AMP_GAIN_MUTE,
16631 #define alc662_auto_init_input_src alc882_auto_init_input_src
16633 static int alc662_parse_auto_config(struct hda_codec *codec)
16635 struct alc_spec *spec = codec->spec;
16637 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16639 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16643 if (!spec->autocfg.line_outs)
16644 return 0; /* can't find valid BIOS pin config */
16646 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16649 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16652 err = alc662_auto_create_extra_out(spec,
16653 spec->autocfg.speaker_pins[0],
16657 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16661 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16665 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16667 if (spec->autocfg.dig_out_pin)
16668 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16670 if (spec->kctls.list)
16671 add_mixer(spec, spec->kctls.list);
16673 spec->num_mux_defs = 1;
16674 spec->input_mux = &spec->private_imux[0];
16676 add_verb(spec, alc662_auto_init_verbs);
16677 if (codec->vendor_id == 0x10ec0663)
16678 add_verb(spec, alc663_auto_init_verbs);
16680 err = alc_auto_add_mic_boost(codec);
16684 store_pin_configs(codec);
16688 /* additional initialization for auto-configuration model */
16689 static void alc662_auto_init(struct hda_codec *codec)
16691 struct alc_spec *spec = codec->spec;
16692 alc662_auto_init_multi_out(codec);
16693 alc662_auto_init_hp_out(codec);
16694 alc662_auto_init_analog_input(codec);
16695 alc662_auto_init_input_src(codec);
16696 if (spec->unsol_event)
16697 alc_inithook(codec);
16700 static int patch_alc662(struct hda_codec *codec)
16702 struct alc_spec *spec;
16703 int err, board_config;
16705 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16709 codec->spec = spec;
16711 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16713 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16716 if (board_config < 0) {
16717 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16718 "trying auto-probe from BIOS...\n");
16719 board_config = ALC662_AUTO;
16722 if (board_config == ALC662_AUTO) {
16723 /* automatic parse from the BIOS config */
16724 err = alc662_parse_auto_config(codec);
16730 "hda_codec: Cannot set up configuration "
16731 "from BIOS. Using base mode...\n");
16732 board_config = ALC662_3ST_2ch_DIG;
16736 if (board_config != ALC662_AUTO)
16737 setup_preset(spec, &alc662_presets[board_config]);
16739 if (codec->vendor_id == 0x10ec0663) {
16740 spec->stream_name_analog = "ALC663 Analog";
16741 spec->stream_name_digital = "ALC663 Digital";
16742 } else if (codec->vendor_id == 0x10ec0272) {
16743 spec->stream_name_analog = "ALC272 Analog";
16744 spec->stream_name_digital = "ALC272 Digital";
16746 spec->stream_name_analog = "ALC662 Analog";
16747 spec->stream_name_digital = "ALC662 Digital";
16750 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16751 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16753 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16754 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16756 spec->adc_nids = alc662_adc_nids;
16757 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16758 spec->capsrc_nids = alc662_capsrc_nids;
16759 spec->capture_style = CAPT_MIX;
16761 if (!spec->cap_mixer)
16762 set_capture_mixer(spec);
16764 spec->vmaster_nid = 0x02;
16766 codec->patch_ops = alc_patch_ops;
16767 if (board_config == ALC662_AUTO)
16768 spec->init_hook = alc662_auto_init;
16769 #ifdef CONFIG_SND_HDA_POWER_SAVE
16770 if (!spec->loopback.amplist)
16771 spec->loopback.amplist = alc662_loopbacks;
16773 codec->proc_widget_hook = print_realtek_coef;
16781 static struct hda_codec_preset snd_hda_preset_realtek[] = {
16782 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16783 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16784 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16785 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16786 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16787 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
16788 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16789 .patch = patch_alc861 },
16790 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16791 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16792 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16793 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16794 .patch = patch_alc883 },
16795 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16796 .patch = patch_alc662 },
16797 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16798 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16799 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16800 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16801 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16802 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16803 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16804 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16805 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16806 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
16807 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16808 .patch = patch_alc883 },
16809 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16810 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16811 {} /* terminator */
16814 MODULE_ALIAS("snd-hda-codec-id:10ec*");
16816 MODULE_LICENSE("GPL");
16817 MODULE_DESCRIPTION("Realtek HD-audio codec");
16819 static struct hda_codec_preset_list realtek_list = {
16820 .preset = snd_hda_preset_realtek,
16821 .owner = THIS_MODULE,
16824 static int __init patch_realtek_init(void)
16826 return snd_hda_add_codec_preset(&realtek_list);
16829 static void __exit patch_realtek_exit(void)
16831 snd_hda_delete_codec_preset(&realtek_list);
16834 module_init(patch_realtek_init)
16835 module_exit(patch_realtek_exit)