2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include "hda_codec.h"
32 #include "hda_local.h"
35 #define ALC880_FRONT_EVENT 0x01
36 #define ALC880_DCVOL_EVENT 0x02
37 #define ALC880_HP_EVENT 0x04
38 #define ALC880_MIC_EVENT 0x08
40 /* ALC880 board config type */
64 #ifdef CONFIG_SND_DEBUG
68 ALC880_MODEL_LAST /* last tag */
82 #ifdef CONFIG_SND_DEBUG
86 ALC260_MODEL_LAST /* last tag */
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
110 ALC262_MODEL_LAST /* last tag */
120 ALC268_ACER_ASPIRE_ONE,
123 #ifdef CONFIG_SND_DEBUG
127 ALC268_MODEL_LAST /* last tag */
134 ALC269_ASUS_EEEPC_P703,
135 ALC269_ASUS_EEEPC_P901,
139 ALC269_MODEL_LAST /* last tag */
156 /* ALC861-VD models */
178 ALC662_ASUS_EEEPC_P701,
179 ALC662_ASUS_EEEPC_EP20,
220 ALC883_TARGA_2ch_DIG,
223 ALC888_ACER_ASPIRE_4930G,
227 ALC883_LENOVO_101E_2ch,
228 ALC883_LENOVO_NB0763,
229 ALC888_LENOVO_MS7195_DIG,
236 ALC883_FUJITSU_PI2515,
237 ALC888_FUJITSU_XA3530,
238 ALC883_3ST_6ch_INTEL,
246 /* styles of capture selection */
248 CAPT_MUX = 0, /* only mux based */
249 CAPT_MIX, /* only mixer based */
250 CAPT_1MUX_MIX, /* first mux and other mixers */
254 #define GPIO_MASK 0x03
257 /* codec parameterization */
258 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
259 unsigned int num_mixers;
260 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
261 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
263 const struct hda_verb *init_verbs[5]; /* initialization verbs
267 unsigned int num_init_verbs;
269 char *stream_name_analog; /* analog PCM stream */
270 struct hda_pcm_stream *stream_analog_playback;
271 struct hda_pcm_stream *stream_analog_capture;
272 struct hda_pcm_stream *stream_analog_alt_playback;
273 struct hda_pcm_stream *stream_analog_alt_capture;
275 char *stream_name_digital; /* digital PCM stream */
276 struct hda_pcm_stream *stream_digital_playback;
277 struct hda_pcm_stream *stream_digital_capture;
280 struct hda_multi_out multiout; /* playback set-up
281 * max_channels, dacs must be set
282 * dig_out_nid and hp_nid are optional
284 hda_nid_t alt_dac_nid;
285 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
289 unsigned int num_adc_nids;
291 hda_nid_t *capsrc_nids;
292 hda_nid_t dig_in_nid; /* digital-in NID; optional */
293 int capture_style; /* capture style (CAPT_*) */
296 unsigned int num_mux_defs;
297 const struct hda_input_mux *input_mux;
298 unsigned int cur_mux[3];
301 const struct hda_channel_mode *channel_mode;
302 int num_channel_mode;
305 /* PCM information */
306 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
308 /* dynamic controls, init_verbs and input_mux */
309 struct auto_pin_cfg autocfg;
310 struct snd_array kctls;
311 struct hda_input_mux private_imux[3];
312 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
315 void (*init_hook)(struct hda_codec *codec);
316 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
318 /* for pin sensing */
319 unsigned int sense_updated: 1;
320 unsigned int jack_present: 1;
321 unsigned int master_sw: 1;
324 unsigned int no_analog :1; /* digital I/O only */
326 /* for virtual master */
327 hda_nid_t vmaster_nid;
328 #ifdef CONFIG_SND_HDA_POWER_SAVE
329 struct hda_loopback_check loopback;
334 unsigned int pll_coef_idx, pll_coef_bit;
338 * configuration template - to be copied to the spec instance
340 struct alc_config_preset {
341 struct snd_kcontrol_new *mixers[5]; /* should be identical size
344 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
345 const struct hda_verb *init_verbs[5];
346 unsigned int num_dacs;
348 hda_nid_t dig_out_nid; /* optional */
349 hda_nid_t hp_nid; /* optional */
350 hda_nid_t *slave_dig_outs;
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 */
766 * set up the input pin config (depending on the given auto-pin type)
768 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
771 unsigned int val = PIN_IN;
773 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
775 pincap = snd_hda_query_pin_caps(codec, nid);
776 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
777 if (pincap & AC_PINCAP_VREF_80)
780 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
785 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
787 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
789 spec->mixers[spec->num_mixers++] = mix;
792 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
794 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
796 spec->init_verbs[spec->num_init_verbs++] = verb;
799 #ifdef CONFIG_PROC_FS
803 static void print_realtek_coef(struct snd_info_buffer *buffer,
804 struct hda_codec *codec, hda_nid_t nid)
810 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
811 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
812 coeff = snd_hda_codec_read(codec, nid, 0,
813 AC_VERB_GET_COEF_INDEX, 0);
814 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
817 #define print_realtek_coef NULL
821 * set up from the preset table
823 static void setup_preset(struct alc_spec *spec,
824 const struct alc_config_preset *preset)
828 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
829 add_mixer(spec, preset->mixers[i]);
830 spec->cap_mixer = preset->cap_mixer;
831 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
833 add_verb(spec, preset->init_verbs[i]);
835 spec->channel_mode = preset->channel_mode;
836 spec->num_channel_mode = preset->num_channel_mode;
837 spec->need_dac_fix = preset->need_dac_fix;
839 spec->multiout.max_channels = spec->channel_mode[0].channels;
841 spec->multiout.num_dacs = preset->num_dacs;
842 spec->multiout.dac_nids = preset->dac_nids;
843 spec->multiout.dig_out_nid = preset->dig_out_nid;
844 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
845 spec->multiout.hp_nid = preset->hp_nid;
847 spec->num_mux_defs = preset->num_mux_defs;
848 if (!spec->num_mux_defs)
849 spec->num_mux_defs = 1;
850 spec->input_mux = preset->input_mux;
852 spec->num_adc_nids = preset->num_adc_nids;
853 spec->adc_nids = preset->adc_nids;
854 spec->capsrc_nids = preset->capsrc_nids;
855 spec->dig_in_nid = preset->dig_in_nid;
857 spec->unsol_event = preset->unsol_event;
858 spec->init_hook = preset->init_hook;
859 #ifdef CONFIG_SND_HDA_POWER_SAVE
860 spec->loopback.amplist = preset->loopbacks;
864 /* Enable GPIO mask and set output */
865 static struct hda_verb alc_gpio1_init_verbs[] = {
866 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
867 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
868 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
872 static struct hda_verb alc_gpio2_init_verbs[] = {
873 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
874 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
875 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
879 static struct hda_verb alc_gpio3_init_verbs[] = {
880 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
881 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
882 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
887 * Fix hardware PLL issue
888 * On some codecs, the analog PLL gating control must be off while
889 * the default value is 1.
891 static void alc_fix_pll(struct hda_codec *codec)
893 struct alc_spec *spec = codec->spec;
898 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
900 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
901 AC_VERB_GET_PROC_COEF, 0);
902 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
904 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
905 val & ~(1 << spec->pll_coef_bit));
908 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
909 unsigned int coef_idx, unsigned int coef_bit)
911 struct alc_spec *spec = codec->spec;
913 spec->pll_coef_idx = coef_idx;
914 spec->pll_coef_bit = coef_bit;
918 static void alc_sku_automute(struct hda_codec *codec)
920 struct alc_spec *spec = codec->spec;
921 unsigned int present;
922 unsigned int hp_nid = spec->autocfg.hp_pins[0];
923 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
925 /* need to execute and sync at first */
926 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
927 present = snd_hda_codec_read(codec, hp_nid, 0,
928 AC_VERB_GET_PIN_SENSE, 0);
929 spec->jack_present = (present & 0x80000000) != 0;
930 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
931 spec->jack_present ? 0 : PIN_OUT);
934 #if 0 /* it's broken in some acses -- temporarily disabled */
935 static void alc_mic_automute(struct hda_codec *codec)
937 struct alc_spec *spec = codec->spec;
938 unsigned int present;
939 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
940 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
941 unsigned int mix_nid = spec->capsrc_nids[0];
942 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
944 capsrc_idx_mic = mic_nid - 0x18;
945 capsrc_idx_fmic = fmic_nid - 0x18;
946 present = snd_hda_codec_read(codec, mic_nid, 0,
947 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
948 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
949 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
950 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
951 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
952 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
953 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
956 #define alc_mic_automute(codec) do {} while(0) /* NOP */
957 #endif /* disabled */
959 /* unsolicited event for HP jack sensing */
960 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
962 if (codec->vendor_id == 0x10ec0880)
966 if (res == ALC880_HP_EVENT)
967 alc_sku_automute(codec);
969 if (res == ALC880_MIC_EVENT)
970 alc_mic_automute(codec);
973 static void alc_inithook(struct hda_codec *codec)
975 alc_sku_automute(codec);
976 alc_mic_automute(codec);
979 /* additional initialization for ALC888 variants */
980 static void alc888_coef_init(struct hda_codec *codec)
984 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
985 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
986 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
987 if ((tmp & 0xf0) == 0x20)
989 snd_hda_codec_read(codec, 0x20, 0,
990 AC_VERB_SET_PROC_COEF, 0x830);
993 snd_hda_codec_read(codec, 0x20, 0,
994 AC_VERB_SET_PROC_COEF, 0x3030);
997 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
998 * 31 ~ 16 : Manufacture ID
1000 * 7 ~ 0 : Assembly ID
1001 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1003 static void alc_subsystem_id(struct hda_codec *codec,
1004 unsigned int porta, unsigned int porte,
1007 unsigned int ass, tmp, i;
1009 struct alc_spec *spec = codec->spec;
1011 ass = codec->subsystem_id & 0xffff;
1012 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1016 * 31~30 : port conetcivity
1019 * 19~16 : Check sum (15:1)
1024 if (codec->vendor_id == 0x10ec0260)
1026 ass = snd_hda_codec_get_pincfg(codec, nid);
1027 snd_printd("realtek: No valid SSID, "
1028 "checking pincfg 0x%08x for NID 0x%x\n",
1030 if (!(ass & 1) && !(ass & 0x100000))
1032 if ((ass >> 30) != 1) /* no physical connection */
1037 for (i = 1; i < 16; i++) {
1041 if (((ass >> 16) & 0xf) != tmp)
1044 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1045 ass & 0xffff, codec->vendor_id);
1049 * 2 : 0 --> Desktop, 1 --> Laptop
1050 * 3~5 : External Amplifier control
1053 tmp = (ass & 0x38) >> 3; /* external Amp control */
1056 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1059 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1062 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1064 case 5: /* set EAPD output high */
1065 switch (codec->vendor_id) {
1067 snd_hda_codec_write(codec, 0x0f, 0,
1068 AC_VERB_SET_EAPD_BTLENABLE, 2);
1069 snd_hda_codec_write(codec, 0x10, 0,
1070 AC_VERB_SET_EAPD_BTLENABLE, 2);
1082 snd_hda_codec_write(codec, 0x14, 0,
1083 AC_VERB_SET_EAPD_BTLENABLE, 2);
1084 snd_hda_codec_write(codec, 0x15, 0,
1085 AC_VERB_SET_EAPD_BTLENABLE, 2);
1088 switch (codec->vendor_id) {
1090 snd_hda_codec_write(codec, 0x1a, 0,
1091 AC_VERB_SET_COEF_INDEX, 7);
1092 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1093 AC_VERB_GET_PROC_COEF, 0);
1094 snd_hda_codec_write(codec, 0x1a, 0,
1095 AC_VERB_SET_COEF_INDEX, 7);
1096 snd_hda_codec_write(codec, 0x1a, 0,
1097 AC_VERB_SET_PROC_COEF,
1107 snd_hda_codec_write(codec, 0x20, 0,
1108 AC_VERB_SET_COEF_INDEX, 7);
1109 tmp = snd_hda_codec_read(codec, 0x20, 0,
1110 AC_VERB_GET_PROC_COEF, 0);
1111 snd_hda_codec_write(codec, 0x20, 0,
1112 AC_VERB_SET_COEF_INDEX, 7);
1113 snd_hda_codec_write(codec, 0x20, 0,
1114 AC_VERB_SET_PROC_COEF,
1118 /*alc888_coef_init(codec);*/ /* called in alc_init() */
1122 snd_hda_codec_write(codec, 0x20, 0,
1123 AC_VERB_SET_COEF_INDEX, 7);
1124 tmp = snd_hda_codec_read(codec, 0x20, 0,
1125 AC_VERB_GET_PROC_COEF, 0);
1126 snd_hda_codec_write(codec, 0x20, 0,
1127 AC_VERB_SET_COEF_INDEX, 7);
1128 snd_hda_codec_write(codec, 0x20, 0,
1129 AC_VERB_SET_PROC_COEF,
1137 /* is laptop or Desktop and enable the function "Mute internal speaker
1138 * when the external headphone out jack is plugged"
1140 if (!(ass & 0x8000))
1143 * 10~8 : Jack location
1144 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1146 * 15 : 1 --> enable the function "Mute internal speaker
1147 * when the external headphone out jack is plugged"
1149 if (!spec->autocfg.speaker_pins[0]) {
1150 if (spec->autocfg.line_out_pins[0])
1151 spec->autocfg.speaker_pins[0] =
1152 spec->autocfg.line_out_pins[0];
1157 if (!spec->autocfg.hp_pins[0]) {
1158 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1160 spec->autocfg.hp_pins[0] = porta;
1162 spec->autocfg.hp_pins[0] = porte;
1164 spec->autocfg.hp_pins[0] = portd;
1168 if (spec->autocfg.hp_pins[0])
1169 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1170 AC_VERB_SET_UNSOLICITED_ENABLE,
1171 AC_USRSP_EN | ALC880_HP_EVENT);
1173 #if 0 /* it's broken in some acses -- temporarily disabled */
1174 if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1175 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1176 snd_hda_codec_write(codec,
1177 spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1178 AC_VERB_SET_UNSOLICITED_ENABLE,
1179 AC_USRSP_EN | ALC880_MIC_EVENT);
1180 #endif /* disabled */
1182 spec->unsol_event = alc_sku_unsol_event;
1186 * Fix-up pin default configurations
1194 static void alc_fix_pincfg(struct hda_codec *codec,
1195 const struct snd_pci_quirk *quirk,
1196 const struct alc_pincfg **pinfix)
1198 const struct alc_pincfg *cfg;
1200 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1204 cfg = pinfix[quirk->value];
1205 for (; cfg->nid; cfg++)
1206 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1216 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1217 /* Mic-in jack as mic in */
1218 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1219 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1220 /* Line-in jack as Line in */
1221 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1222 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1223 /* Line-Out as Front */
1224 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1231 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1232 /* Mic-in jack as mic in */
1233 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1234 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1235 /* Line-in jack as Surround */
1236 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1237 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1238 /* Line-Out as Front */
1239 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1246 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1247 /* Mic-in jack as CLFE */
1248 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1249 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1250 /* Line-in jack as Surround */
1251 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1252 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1253 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1254 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1261 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1262 /* Mic-in jack as CLFE */
1263 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1264 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1265 /* Line-in jack as Surround */
1266 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1267 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1268 /* Line-Out as Side */
1269 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1273 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1274 { 2, alc888_4ST_ch2_intel_init },
1275 { 4, alc888_4ST_ch4_intel_init },
1276 { 6, alc888_4ST_ch6_intel_init },
1277 { 8, alc888_4ST_ch8_intel_init },
1281 * ALC888 Fujitsu Siemens Amillo xa3530
1284 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1285 /* Front Mic: set to PIN_IN (empty by default) */
1286 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1287 /* Connect Internal HP to Front */
1288 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1289 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1290 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1291 /* Connect Bass HP to Front */
1292 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1293 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1294 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1295 /* Connect Line-Out side jack (SPDIF) to Side */
1296 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1297 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1298 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1299 /* Connect Mic jack to CLFE */
1300 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1301 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1302 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1303 /* Connect Line-in jack to Surround */
1304 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1305 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1306 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1307 /* Connect HP out jack to Front */
1308 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1309 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1310 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1311 /* Enable unsolicited event for HP jack and Line-out jack */
1312 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1313 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1317 static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec)
1319 unsigned int present;
1321 /* Line out presence */
1322 present = snd_hda_codec_read(codec, 0x17, 0,
1323 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1324 /* HP out presence */
1325 present = present || snd_hda_codec_read(codec, 0x1b, 0,
1326 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1327 bits = present ? HDA_AMP_MUTE : 0;
1328 /* Toggle internal speakers muting */
1329 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1330 HDA_AMP_MUTE, bits);
1331 /* Toggle internal bass muting */
1332 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1333 HDA_AMP_MUTE, bits);
1336 static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec,
1339 if (res >> 26 == ALC880_HP_EVENT)
1340 alc888_fujitsu_xa3530_automute(codec);
1345 * ALC888 Acer Aspire 4930G model
1348 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1349 /* Front Mic: set to PIN_IN (empty by default) */
1350 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1351 /* Unselect Front Mic by default in input mixer 3 */
1352 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1353 /* Enable unsolicited event for HP jack */
1354 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1355 /* Connect Internal HP to front */
1356 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1357 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1358 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1359 /* Connect HP out to front */
1360 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1361 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1362 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1366 static struct hda_input_mux alc888_2_capture_sources[2] = {
1367 /* Front mic only available on one ADC */
1374 { "Front Mic", 0xb },
1387 static struct snd_kcontrol_new alc888_base_mixer[] = {
1388 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1389 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1390 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1391 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1392 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1394 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1395 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1396 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1397 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1398 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1399 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1400 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1401 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1402 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1404 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1409 static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec)
1411 unsigned int present;
1413 present = snd_hda_codec_read(codec, 0x15, 0,
1414 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1415 bits = present ? HDA_AMP_MUTE : 0;
1416 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1417 HDA_AMP_MUTE, bits);
1420 static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec,
1423 if (res >> 26 == ALC880_HP_EVENT)
1424 alc888_acer_aspire_4930g_automute(codec);
1428 * ALC880 3-stack model
1430 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1431 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1432 * F-Mic = 0x1b, HP = 0x19
1435 static hda_nid_t alc880_dac_nids[4] = {
1436 /* front, rear, clfe, rear_surr */
1437 0x02, 0x05, 0x04, 0x03
1440 static hda_nid_t alc880_adc_nids[3] = {
1445 /* The datasheet says the node 0x07 is connected from inputs,
1446 * but it shows zero connection in the real implementation on some devices.
1447 * Note: this is a 915GAV bug, fixed on 915GLV
1449 static hda_nid_t alc880_adc_nids_alt[2] = {
1454 #define ALC880_DIGOUT_NID 0x06
1455 #define ALC880_DIGIN_NID 0x0a
1457 static struct hda_input_mux alc880_capture_source = {
1461 { "Front Mic", 0x3 },
1467 /* channel source setting (2/6 channel selection for 3-stack) */
1469 static struct hda_verb alc880_threestack_ch2_init[] = {
1470 /* set line-in to input, mute it */
1471 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1472 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1473 /* set mic-in to input vref 80%, mute it */
1474 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1475 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1480 static struct hda_verb alc880_threestack_ch6_init[] = {
1481 /* set line-in to output, unmute it */
1482 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1483 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1484 /* set mic-in to output, unmute it */
1485 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1486 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1490 static struct hda_channel_mode alc880_threestack_modes[2] = {
1491 { 2, alc880_threestack_ch2_init },
1492 { 6, alc880_threestack_ch6_init },
1495 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1496 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1497 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1498 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1499 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1500 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1501 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1502 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1503 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1504 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1505 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1506 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1507 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1509 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1510 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1511 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1512 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1514 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1515 .name = "Channel Mode",
1516 .info = alc_ch_mode_info,
1517 .get = alc_ch_mode_get,
1518 .put = alc_ch_mode_put,
1523 /* capture mixer elements */
1524 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1525 struct snd_ctl_elem_info *uinfo)
1527 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1528 struct alc_spec *spec = codec->spec;
1531 mutex_lock(&codec->control_mutex);
1532 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1534 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1535 mutex_unlock(&codec->control_mutex);
1539 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1540 unsigned int size, unsigned int __user *tlv)
1542 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1543 struct alc_spec *spec = codec->spec;
1546 mutex_lock(&codec->control_mutex);
1547 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1549 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1550 mutex_unlock(&codec->control_mutex);
1554 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1555 struct snd_ctl_elem_value *ucontrol);
1557 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1558 struct snd_ctl_elem_value *ucontrol,
1561 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1562 struct alc_spec *spec = codec->spec;
1563 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1566 mutex_lock(&codec->control_mutex);
1567 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1569 err = func(kcontrol, ucontrol);
1570 mutex_unlock(&codec->control_mutex);
1574 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1575 struct snd_ctl_elem_value *ucontrol)
1577 return alc_cap_getput_caller(kcontrol, ucontrol,
1578 snd_hda_mixer_amp_volume_get);
1581 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1582 struct snd_ctl_elem_value *ucontrol)
1584 return alc_cap_getput_caller(kcontrol, ucontrol,
1585 snd_hda_mixer_amp_volume_put);
1588 /* capture mixer elements */
1589 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1591 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1592 struct snd_ctl_elem_value *ucontrol)
1594 return alc_cap_getput_caller(kcontrol, ucontrol,
1595 snd_hda_mixer_amp_switch_get);
1598 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1599 struct snd_ctl_elem_value *ucontrol)
1601 return alc_cap_getput_caller(kcontrol, ucontrol,
1602 snd_hda_mixer_amp_switch_put);
1605 #define _DEFINE_CAPMIX(num) \
1607 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1608 .name = "Capture Switch", \
1609 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1611 .info = alc_cap_sw_info, \
1612 .get = alc_cap_sw_get, \
1613 .put = alc_cap_sw_put, \
1616 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1617 .name = "Capture Volume", \
1618 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1619 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1620 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1622 .info = alc_cap_vol_info, \
1623 .get = alc_cap_vol_get, \
1624 .put = alc_cap_vol_put, \
1625 .tlv = { .c = alc_cap_vol_tlv }, \
1628 #define _DEFINE_CAPSRC(num) \
1630 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1631 /* .name = "Capture Source", */ \
1632 .name = "Input Source", \
1634 .info = alc_mux_enum_info, \
1635 .get = alc_mux_enum_get, \
1636 .put = alc_mux_enum_put, \
1639 #define DEFINE_CAPMIX(num) \
1640 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1641 _DEFINE_CAPMIX(num), \
1642 _DEFINE_CAPSRC(num), \
1646 #define DEFINE_CAPMIX_NOSRC(num) \
1647 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1648 _DEFINE_CAPMIX(num), \
1652 /* up to three ADCs */
1656 DEFINE_CAPMIX_NOSRC(1);
1657 DEFINE_CAPMIX_NOSRC(2);
1658 DEFINE_CAPMIX_NOSRC(3);
1661 * ALC880 5-stack model
1663 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1665 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1666 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1669 /* additional mixers to alc880_three_stack_mixer */
1670 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1671 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1672 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1676 /* channel source setting (6/8 channel selection for 5-stack) */
1678 static struct hda_verb alc880_fivestack_ch6_init[] = {
1679 /* set line-in to input, mute it */
1680 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1681 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1686 static struct hda_verb alc880_fivestack_ch8_init[] = {
1687 /* set line-in to output, unmute it */
1688 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1689 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1693 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1694 { 6, alc880_fivestack_ch6_init },
1695 { 8, alc880_fivestack_ch8_init },
1700 * ALC880 6-stack model
1702 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1703 * Side = 0x05 (0x0f)
1704 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1705 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1708 static hda_nid_t alc880_6st_dac_nids[4] = {
1709 /* front, rear, clfe, rear_surr */
1710 0x02, 0x03, 0x04, 0x05
1713 static struct hda_input_mux alc880_6stack_capture_source = {
1717 { "Front Mic", 0x1 },
1723 /* fixed 8-channels */
1724 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1728 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1729 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1730 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1731 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1732 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1733 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1734 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1735 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1736 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1737 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1738 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1739 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1740 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1741 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1742 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1743 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1744 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1745 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1746 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1749 .name = "Channel Mode",
1750 .info = alc_ch_mode_info,
1751 .get = alc_ch_mode_get,
1752 .put = alc_ch_mode_put,
1761 * W810 has rear IO for:
1764 * Center/LFE (DAC 04)
1767 * The system also has a pair of internal speakers, and a headphone jack.
1768 * These are both connected to Line2 on the codec, hence to DAC 02.
1770 * There is a variable resistor to control the speaker or headphone
1771 * volume. This is a hardware-only device without a software API.
1773 * Plugging headphones in will disable the internal speakers. This is
1774 * implemented in hardware, not via the driver using jack sense. In
1775 * a similar fashion, plugging into the rear socket marked "front" will
1776 * disable both the speakers and headphones.
1778 * For input, there's a microphone jack, and an "audio in" jack.
1779 * These may not do anything useful with this driver yet, because I
1780 * haven't setup any initialization verbs for these yet...
1783 static hda_nid_t alc880_w810_dac_nids[3] = {
1784 /* front, rear/surround, clfe */
1788 /* fixed 6 channels */
1789 static struct hda_channel_mode alc880_w810_modes[1] = {
1793 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1794 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1795 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1796 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1797 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1798 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1799 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1800 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1801 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1802 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1803 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1811 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1812 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1816 static hda_nid_t alc880_z71v_dac_nids[1] = {
1819 #define ALC880_Z71V_HP_DAC 0x03
1821 /* fixed 2 channels */
1822 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1826 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1827 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1828 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1829 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1830 HDA_BIND_MUTE("Headphone 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, 0x0, HDA_INPUT),
1834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1840 * ALC880 F1734 model
1842 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1843 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1846 static hda_nid_t alc880_f1734_dac_nids[1] = {
1849 #define ALC880_F1734_HP_DAC 0x02
1851 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1852 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1853 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1854 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1855 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1856 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1857 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1858 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1859 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1863 static struct hda_input_mux alc880_f1734_capture_source = {
1875 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1876 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1877 * Mic = 0x18, Line = 0x1a
1880 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1881 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1883 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1884 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1885 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1886 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1887 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1888 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1889 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1890 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1891 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1892 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1893 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1894 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1895 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1896 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1897 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1899 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1900 .name = "Channel Mode",
1901 .info = alc_ch_mode_info,
1902 .get = alc_ch_mode_get,
1903 .put = alc_ch_mode_put,
1909 * ALC880 ASUS W1V model
1911 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1912 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1913 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1916 /* additional mixers to alc880_asus_mixer */
1917 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1918 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1919 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1924 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1925 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1926 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1927 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1928 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1929 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1930 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1931 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1932 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1933 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1938 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1939 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1940 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1941 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1942 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1943 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1944 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1945 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1946 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1947 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1948 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1949 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1950 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1951 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1952 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1953 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1954 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1956 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1957 .name = "Channel Mode",
1958 .info = alc_ch_mode_info,
1959 .get = alc_ch_mode_get,
1960 .put = alc_ch_mode_put,
1965 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1966 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1967 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1968 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1969 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1970 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1971 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1972 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1973 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1974 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1975 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1979 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1980 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1981 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1982 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1983 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1984 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1985 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1990 * virtual master controls
1994 * slave controls for virtual master
1996 static const char *alc_slave_vols[] = {
1997 "Front Playback Volume",
1998 "Surround Playback Volume",
1999 "Center Playback Volume",
2000 "LFE Playback Volume",
2001 "Side Playback Volume",
2002 "Headphone Playback Volume",
2003 "Speaker Playback Volume",
2004 "Mono Playback Volume",
2005 "Line-Out Playback Volume",
2006 "PCM Playback Volume",
2010 static const char *alc_slave_sws[] = {
2011 "Front Playback Switch",
2012 "Surround Playback Switch",
2013 "Center Playback Switch",
2014 "LFE Playback Switch",
2015 "Side Playback Switch",
2016 "Headphone Playback Switch",
2017 "Speaker Playback Switch",
2018 "Mono Playback Switch",
2019 "IEC958 Playback Switch",
2024 * build control elements
2027 static void alc_free_kctls(struct hda_codec *codec);
2029 /* additional beep mixers; the actual parameters are overwritten at build */
2030 static struct snd_kcontrol_new alc_beep_mixer[] = {
2031 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2032 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2036 static int alc_build_controls(struct hda_codec *codec)
2038 struct alc_spec *spec = codec->spec;
2042 for (i = 0; i < spec->num_mixers; i++) {
2043 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2047 if (spec->cap_mixer) {
2048 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2052 if (spec->multiout.dig_out_nid) {
2053 err = snd_hda_create_spdif_out_ctls(codec,
2054 spec->multiout.dig_out_nid);
2057 if (!spec->no_analog) {
2058 err = snd_hda_create_spdif_share_sw(codec,
2062 spec->multiout.share_spdif = 1;
2065 if (spec->dig_in_nid) {
2066 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2071 /* create beep controls if needed */
2072 if (spec->beep_amp) {
2073 struct snd_kcontrol_new *knew;
2074 for (knew = alc_beep_mixer; knew->name; knew++) {
2075 struct snd_kcontrol *kctl;
2076 kctl = snd_ctl_new1(knew, codec);
2079 kctl->private_value = spec->beep_amp;
2080 err = snd_hda_ctl_add(codec, kctl);
2086 /* if we have no master control, let's create it */
2087 if (!spec->no_analog &&
2088 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2089 unsigned int vmaster_tlv[4];
2090 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2091 HDA_OUTPUT, vmaster_tlv);
2092 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2093 vmaster_tlv, alc_slave_vols);
2097 if (!spec->no_analog &&
2098 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2099 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2100 NULL, alc_slave_sws);
2105 alc_free_kctls(codec); /* no longer needed */
2111 * initialize the codec volumes, etc
2115 * generic initialization of ADC, input mixers and output mixers
2117 static struct hda_verb alc880_volume_init_verbs[] = {
2119 * Unmute ADC0-2 and set the default input to mic-in
2121 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2122 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2123 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2124 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2125 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2126 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2128 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2130 * Note: PASD motherboards uses the Line In 2 as the input for front
2133 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2134 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2135 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2136 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2137 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2138 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2139 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2140 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2143 * Set up output mixers (0x0c - 0x0f)
2145 /* set vol=0 to output mixers */
2146 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2147 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2148 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2149 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2150 /* set up input amps for analog loopback */
2151 /* Amp Indices: DAC = 0, mixer = 1 */
2152 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2153 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2154 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2155 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2156 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2157 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2158 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2159 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2165 * 3-stack pin configuration:
2166 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2168 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2170 * preset connection lists of input pins
2171 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2173 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2174 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2175 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2178 * Set pin mode and muting
2180 /* set front pin widgets 0x14 for output */
2181 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2182 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2183 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2184 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2185 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2186 /* Mic2 (as headphone out) for HP output */
2187 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2188 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2189 /* Line In pin widget for input */
2190 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2191 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2192 /* Line2 (as front mic) pin widget for input and vref at 80% */
2193 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2194 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2195 /* CD pin widget for input */
2196 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2202 * 5-stack pin configuration:
2203 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2204 * line-in/side = 0x1a, f-mic = 0x1b
2206 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2208 * preset connection lists of input pins
2209 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2211 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2212 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2215 * Set pin mode and muting
2217 /* set pin widgets 0x14-0x17 for output */
2218 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2219 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2220 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2221 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2222 /* unmute pins for output (no gain on this amp) */
2223 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2224 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2225 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2226 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2228 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2229 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2230 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2231 /* Mic2 (as headphone out) for HP output */
2232 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2233 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2234 /* Line In pin widget for input */
2235 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2236 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2237 /* Line2 (as front mic) pin widget for input and vref at 80% */
2238 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2239 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2240 /* CD pin widget for input */
2241 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2247 * W810 pin configuration:
2248 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2250 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2251 /* hphone/speaker input selector: front DAC */
2252 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2254 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2255 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2256 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2257 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2258 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2259 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2261 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2262 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2268 * Z71V pin configuration:
2269 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2271 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2272 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2273 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2274 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2275 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2277 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2278 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2279 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2280 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2286 * 6-stack pin configuration:
2287 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2288 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2290 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2291 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2293 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2294 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2295 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2296 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2297 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2298 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2299 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2300 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2302 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2303 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2304 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2305 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2306 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2307 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2308 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2309 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2310 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2316 * Uniwill pin configuration:
2317 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2320 static struct hda_verb alc880_uniwill_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 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2330 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2333 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2334 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2335 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2336 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2338 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2339 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2340 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2341 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2342 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2343 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2344 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2345 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2346 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2348 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2349 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2356 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2358 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2359 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2361 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2362 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2363 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2364 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2365 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2366 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2368 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2369 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2370 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2371 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2372 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2374 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2375 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2376 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2377 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2378 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2379 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2381 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2382 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2387 static struct hda_verb alc880_beep_init_verbs[] = {
2388 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2392 /* toggle speaker-output according to the hp-jack state */
2393 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
2395 unsigned int present;
2398 present = snd_hda_codec_read(codec, 0x14, 0,
2399 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2400 bits = present ? HDA_AMP_MUTE : 0;
2401 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2402 HDA_AMP_MUTE, bits);
2403 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2404 HDA_AMP_MUTE, bits);
2407 /* auto-toggle front mic */
2408 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2410 unsigned int present;
2413 present = snd_hda_codec_read(codec, 0x18, 0,
2414 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2415 bits = present ? HDA_AMP_MUTE : 0;
2416 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2419 static void alc880_uniwill_automute(struct hda_codec *codec)
2421 alc880_uniwill_hp_automute(codec);
2422 alc880_uniwill_mic_automute(codec);
2425 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2428 /* Looks like the unsol event is incompatible with the standard
2429 * definition. 4bit tag is placed at 28 bit!
2431 switch (res >> 28) {
2432 case ALC880_HP_EVENT:
2433 alc880_uniwill_hp_automute(codec);
2435 case ALC880_MIC_EVENT:
2436 alc880_uniwill_mic_automute(codec);
2441 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2443 unsigned int present;
2446 present = snd_hda_codec_read(codec, 0x14, 0,
2447 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2448 bits = present ? HDA_AMP_MUTE : 0;
2449 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2452 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2454 unsigned int present;
2456 present = snd_hda_codec_read(codec, 0x21, 0,
2457 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2458 present &= HDA_AMP_VOLMASK;
2459 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2460 HDA_AMP_VOLMASK, present);
2461 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2462 HDA_AMP_VOLMASK, present);
2465 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2468 /* Looks like the unsol event is incompatible with the standard
2469 * definition. 4bit tag is placed at 28 bit!
2471 if ((res >> 28) == ALC880_HP_EVENT)
2472 alc880_uniwill_p53_hp_automute(codec);
2473 if ((res >> 28) == ALC880_DCVOL_EVENT)
2474 alc880_uniwill_p53_dcvol_automute(codec);
2478 * F1734 pin configuration:
2479 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2481 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2482 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2483 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2484 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2485 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2486 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2488 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2489 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2490 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2491 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2493 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2494 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2495 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2496 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2497 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2498 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2499 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2500 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2501 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2503 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2504 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2510 * ASUS pin configuration:
2511 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2513 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2514 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2515 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2516 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2517 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2519 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2520 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2522 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2523 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2524 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2525 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2526 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2528 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2529 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2530 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2531 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2532 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2534 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2535 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2536 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2541 /* Enable GPIO mask and set output */
2542 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2543 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2545 /* Clevo m520g init */
2546 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2547 /* headphone output */
2548 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2550 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2551 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2553 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2554 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2556 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2557 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2558 /* Mic1 (rear panel) */
2559 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2560 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2561 /* Mic2 (front panel) */
2562 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2563 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2565 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2566 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2567 /* change to EAPD mode */
2568 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2569 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2574 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2575 /* change to EAPD mode */
2576 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2577 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2579 /* Headphone output */
2580 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2582 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2583 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2585 /* Line In pin widget for input */
2586 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2587 /* CD pin widget for input */
2588 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2589 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2590 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2592 /* change to EAPD mode */
2593 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2594 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2600 * LG m1 express dual
2603 * Rear Line-In/Out (blue): 0x14
2604 * Build-in Mic-In: 0x15
2606 * HP-Out (green): 0x1b
2607 * Mic-In/Out (red): 0x19
2611 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2612 static hda_nid_t alc880_lg_dac_nids[3] = {
2616 /* seems analog CD is not working */
2617 static struct hda_input_mux alc880_lg_capture_source = {
2622 { "Internal Mic", 0x6 },
2626 /* 2,4,6 channel modes */
2627 static struct hda_verb alc880_lg_ch2_init[] = {
2628 /* set line-in and mic-in to input */
2629 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2630 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2634 static struct hda_verb alc880_lg_ch4_init[] = {
2635 /* set line-in to out and mic-in to input */
2636 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2637 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2641 static struct hda_verb alc880_lg_ch6_init[] = {
2642 /* set line-in and mic-in to output */
2643 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2644 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2648 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2649 { 2, alc880_lg_ch2_init },
2650 { 4, alc880_lg_ch4_init },
2651 { 6, alc880_lg_ch6_init },
2654 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2655 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2656 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2657 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2658 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2659 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2660 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2661 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2662 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2663 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2664 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2665 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2666 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2667 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2668 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2670 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2671 .name = "Channel Mode",
2672 .info = alc_ch_mode_info,
2673 .get = alc_ch_mode_get,
2674 .put = alc_ch_mode_put,
2679 static struct hda_verb alc880_lg_init_verbs[] = {
2680 /* set capture source to mic-in */
2681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2682 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2683 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2684 /* mute all amp mixer inputs */
2685 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2688 /* line-in to input */
2689 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2690 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2692 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2695 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2696 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2697 /* mic-in to input */
2698 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2699 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2700 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2702 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2703 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2704 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2706 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2710 /* toggle speaker-output according to the hp-jack state */
2711 static void alc880_lg_automute(struct hda_codec *codec)
2713 unsigned int present;
2716 present = snd_hda_codec_read(codec, 0x1b, 0,
2717 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2718 bits = present ? HDA_AMP_MUTE : 0;
2719 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2720 HDA_AMP_MUTE, bits);
2723 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2725 /* Looks like the unsol event is incompatible with the standard
2726 * definition. 4bit tag is placed at 28 bit!
2728 if ((res >> 28) == 0x01)
2729 alc880_lg_automute(codec);
2738 * Built-in Mic-In: 0x19
2744 static struct hda_input_mux alc880_lg_lw_capture_source = {
2748 { "Internal Mic", 0x1 },
2753 #define alc880_lg_lw_modes alc880_threestack_modes
2755 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2756 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2757 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2758 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2759 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2760 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2761 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2762 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2763 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2764 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2765 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2766 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2767 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2768 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2769 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2772 .name = "Channel Mode",
2773 .info = alc_ch_mode_info,
2774 .get = alc_ch_mode_get,
2775 .put = alc_ch_mode_put,
2780 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2781 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2782 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2783 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2785 /* set capture source to mic-in */
2786 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2787 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2788 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2789 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2791 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2792 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2794 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2795 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2796 /* mic-in to input */
2797 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2798 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2800 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2801 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2803 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2807 /* toggle speaker-output according to the hp-jack state */
2808 static void alc880_lg_lw_automute(struct hda_codec *codec)
2810 unsigned int present;
2813 present = snd_hda_codec_read(codec, 0x1b, 0,
2814 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2815 bits = present ? HDA_AMP_MUTE : 0;
2816 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2817 HDA_AMP_MUTE, bits);
2820 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2822 /* Looks like the unsol event is incompatible with the standard
2823 * definition. 4bit tag is placed at 28 bit!
2825 if ((res >> 28) == 0x01)
2826 alc880_lg_lw_automute(codec);
2829 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2830 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2831 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2832 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2833 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2834 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2835 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2839 static struct hda_input_mux alc880_medion_rim_capture_source = {
2843 { "Internal Mic", 0x1 },
2847 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2848 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2850 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2851 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2853 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2854 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2855 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2856 /* Mic2 (as headphone out) for HP output */
2857 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2858 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2859 /* Internal Speaker */
2860 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2861 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2863 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2864 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2866 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2870 /* toggle speaker-output according to the hp-jack state */
2871 static void alc880_medion_rim_automute(struct hda_codec *codec)
2873 unsigned int present;
2876 present = snd_hda_codec_read(codec, 0x14, 0,
2877 AC_VERB_GET_PIN_SENSE, 0)
2878 & AC_PINSENSE_PRESENCE;
2879 bits = present ? HDA_AMP_MUTE : 0;
2880 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2881 HDA_AMP_MUTE, bits);
2883 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2885 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2888 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2891 /* Looks like the unsol event is incompatible with the standard
2892 * definition. 4bit tag is placed at 28 bit!
2894 if ((res >> 28) == ALC880_HP_EVENT)
2895 alc880_medion_rim_automute(codec);
2898 #ifdef CONFIG_SND_HDA_POWER_SAVE
2899 static struct hda_amp_list alc880_loopbacks[] = {
2900 { 0x0b, HDA_INPUT, 0 },
2901 { 0x0b, HDA_INPUT, 1 },
2902 { 0x0b, HDA_INPUT, 2 },
2903 { 0x0b, HDA_INPUT, 3 },
2904 { 0x0b, HDA_INPUT, 4 },
2908 static struct hda_amp_list alc880_lg_loopbacks[] = {
2909 { 0x0b, HDA_INPUT, 1 },
2910 { 0x0b, HDA_INPUT, 6 },
2911 { 0x0b, HDA_INPUT, 7 },
2920 static int alc_init(struct hda_codec *codec)
2922 struct alc_spec *spec = codec->spec;
2926 if (codec->vendor_id == 0x10ec0888)
2927 alc888_coef_init(codec);
2929 for (i = 0; i < spec->num_init_verbs; i++)
2930 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2932 if (spec->init_hook)
2933 spec->init_hook(codec);
2938 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2940 struct alc_spec *spec = codec->spec;
2942 if (spec->unsol_event)
2943 spec->unsol_event(codec, res);
2946 #ifdef CONFIG_SND_HDA_POWER_SAVE
2947 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2949 struct alc_spec *spec = codec->spec;
2950 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2955 * Analog playback callbacks
2957 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2958 struct hda_codec *codec,
2959 struct snd_pcm_substream *substream)
2961 struct alc_spec *spec = codec->spec;
2962 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2966 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2967 struct hda_codec *codec,
2968 unsigned int stream_tag,
2969 unsigned int format,
2970 struct snd_pcm_substream *substream)
2972 struct alc_spec *spec = codec->spec;
2973 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2974 stream_tag, format, substream);
2977 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2978 struct hda_codec *codec,
2979 struct snd_pcm_substream *substream)
2981 struct alc_spec *spec = codec->spec;
2982 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2988 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2989 struct hda_codec *codec,
2990 struct snd_pcm_substream *substream)
2992 struct alc_spec *spec = codec->spec;
2993 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2996 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2997 struct hda_codec *codec,
2998 unsigned int stream_tag,
2999 unsigned int format,
3000 struct snd_pcm_substream *substream)
3002 struct alc_spec *spec = codec->spec;
3003 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3004 stream_tag, format, substream);
3007 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3008 struct hda_codec *codec,
3009 struct snd_pcm_substream *substream)
3011 struct alc_spec *spec = codec->spec;
3012 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3015 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3016 struct hda_codec *codec,
3017 struct snd_pcm_substream *substream)
3019 struct alc_spec *spec = codec->spec;
3020 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3026 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3027 struct hda_codec *codec,
3028 unsigned int stream_tag,
3029 unsigned int format,
3030 struct snd_pcm_substream *substream)
3032 struct alc_spec *spec = codec->spec;
3034 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3035 stream_tag, 0, format);
3039 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3040 struct hda_codec *codec,
3041 struct snd_pcm_substream *substream)
3043 struct alc_spec *spec = codec->spec;
3045 snd_hda_codec_cleanup_stream(codec,
3046 spec->adc_nids[substream->number + 1]);
3053 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3057 /* NID is set in alc_build_pcms */
3059 .open = alc880_playback_pcm_open,
3060 .prepare = alc880_playback_pcm_prepare,
3061 .cleanup = alc880_playback_pcm_cleanup
3065 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3069 /* NID is set in alc_build_pcms */
3072 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3076 /* NID is set in alc_build_pcms */
3079 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3080 .substreams = 2, /* can be overridden */
3083 /* NID is set in alc_build_pcms */
3085 .prepare = alc880_alt_capture_pcm_prepare,
3086 .cleanup = alc880_alt_capture_pcm_cleanup
3090 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3094 /* NID is set in alc_build_pcms */
3096 .open = alc880_dig_playback_pcm_open,
3097 .close = alc880_dig_playback_pcm_close,
3098 .prepare = alc880_dig_playback_pcm_prepare,
3099 .cleanup = alc880_dig_playback_pcm_cleanup
3103 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3107 /* NID is set in alc_build_pcms */
3110 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3111 static struct hda_pcm_stream alc_pcm_null_stream = {
3117 static int alc_build_pcms(struct hda_codec *codec)
3119 struct alc_spec *spec = codec->spec;
3120 struct hda_pcm *info = spec->pcm_rec;
3123 codec->num_pcms = 1;
3124 codec->pcm_info = info;
3126 if (spec->no_analog)
3129 info->name = spec->stream_name_analog;
3130 if (spec->stream_analog_playback) {
3131 if (snd_BUG_ON(!spec->multiout.dac_nids))
3133 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3134 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3136 if (spec->stream_analog_capture) {
3137 if (snd_BUG_ON(!spec->adc_nids))
3139 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3140 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3143 if (spec->channel_mode) {
3144 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3145 for (i = 0; i < spec->num_channel_mode; i++) {
3146 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3147 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3153 /* SPDIF for stream index #1 */
3154 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3155 codec->num_pcms = 2;
3156 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3157 info = spec->pcm_rec + 1;
3158 info->name = spec->stream_name_digital;
3159 if (spec->dig_out_type)
3160 info->pcm_type = spec->dig_out_type;
3162 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3163 if (spec->multiout.dig_out_nid &&
3164 spec->stream_digital_playback) {
3165 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3166 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3168 if (spec->dig_in_nid &&
3169 spec->stream_digital_capture) {
3170 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3171 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3173 /* FIXME: do we need this for all Realtek codec models? */
3174 codec->spdif_status_reset = 1;
3177 if (spec->no_analog)
3180 /* If the use of more than one ADC is requested for the current
3181 * model, configure a second analog capture-only PCM.
3183 /* Additional Analaog capture for index #2 */
3184 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3185 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3186 codec->num_pcms = 3;
3187 info = spec->pcm_rec + 2;
3188 info->name = spec->stream_name_analog;
3189 if (spec->alt_dac_nid) {
3190 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3191 *spec->stream_analog_alt_playback;
3192 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3195 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3196 alc_pcm_null_stream;
3197 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3199 if (spec->num_adc_nids > 1) {
3200 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3201 *spec->stream_analog_alt_capture;
3202 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3204 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3205 spec->num_adc_nids - 1;
3207 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3208 alc_pcm_null_stream;
3209 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3216 static void alc_free_kctls(struct hda_codec *codec)
3218 struct alc_spec *spec = codec->spec;
3220 if (spec->kctls.list) {
3221 struct snd_kcontrol_new *kctl = spec->kctls.list;
3223 for (i = 0; i < spec->kctls.used; i++)
3224 kfree(kctl[i].name);
3226 snd_array_free(&spec->kctls);
3229 static void alc_free(struct hda_codec *codec)
3231 struct alc_spec *spec = codec->spec;
3236 alc_free_kctls(codec);
3238 snd_hda_detach_beep_device(codec);
3241 #ifdef SND_HDA_NEEDS_RESUME
3242 static int alc_resume(struct hda_codec *codec)
3244 codec->patch_ops.init(codec);
3245 snd_hda_codec_resume_amp(codec);
3246 snd_hda_codec_resume_cache(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_VENDOR(0x1043, "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),
3631 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3632 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3633 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3638 * ALC880 codec presets
3640 static struct alc_config_preset alc880_presets[] = {
3642 .mixers = { alc880_three_stack_mixer },
3643 .init_verbs = { alc880_volume_init_verbs,
3644 alc880_pin_3stack_init_verbs },
3645 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3646 .dac_nids = alc880_dac_nids,
3647 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3648 .channel_mode = alc880_threestack_modes,
3650 .input_mux = &alc880_capture_source,
3652 [ALC880_3ST_DIG] = {
3653 .mixers = { alc880_three_stack_mixer },
3654 .init_verbs = { alc880_volume_init_verbs,
3655 alc880_pin_3stack_init_verbs },
3656 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3657 .dac_nids = alc880_dac_nids,
3658 .dig_out_nid = ALC880_DIGOUT_NID,
3659 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3660 .channel_mode = alc880_threestack_modes,
3662 .input_mux = &alc880_capture_source,
3664 [ALC880_TCL_S700] = {
3665 .mixers = { alc880_tcl_s700_mixer },
3666 .init_verbs = { alc880_volume_init_verbs,
3667 alc880_pin_tcl_S700_init_verbs,
3668 alc880_gpio2_init_verbs },
3669 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3670 .dac_nids = alc880_dac_nids,
3671 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3672 .num_adc_nids = 1, /* single ADC */
3674 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3675 .channel_mode = alc880_2_jack_modes,
3676 .input_mux = &alc880_capture_source,
3679 .mixers = { alc880_three_stack_mixer,
3680 alc880_five_stack_mixer},
3681 .init_verbs = { alc880_volume_init_verbs,
3682 alc880_pin_5stack_init_verbs },
3683 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3684 .dac_nids = alc880_dac_nids,
3685 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3686 .channel_mode = alc880_fivestack_modes,
3687 .input_mux = &alc880_capture_source,
3689 [ALC880_5ST_DIG] = {
3690 .mixers = { alc880_three_stack_mixer,
3691 alc880_five_stack_mixer },
3692 .init_verbs = { alc880_volume_init_verbs,
3693 alc880_pin_5stack_init_verbs },
3694 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3695 .dac_nids = alc880_dac_nids,
3696 .dig_out_nid = ALC880_DIGOUT_NID,
3697 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3698 .channel_mode = alc880_fivestack_modes,
3699 .input_mux = &alc880_capture_source,
3702 .mixers = { alc880_six_stack_mixer },
3703 .init_verbs = { alc880_volume_init_verbs,
3704 alc880_pin_6stack_init_verbs },
3705 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3706 .dac_nids = alc880_6st_dac_nids,
3707 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3708 .channel_mode = alc880_sixstack_modes,
3709 .input_mux = &alc880_6stack_capture_source,
3711 [ALC880_6ST_DIG] = {
3712 .mixers = { alc880_six_stack_mixer },
3713 .init_verbs = { alc880_volume_init_verbs,
3714 alc880_pin_6stack_init_verbs },
3715 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3716 .dac_nids = alc880_6st_dac_nids,
3717 .dig_out_nid = ALC880_DIGOUT_NID,
3718 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3719 .channel_mode = alc880_sixstack_modes,
3720 .input_mux = &alc880_6stack_capture_source,
3723 .mixers = { alc880_w810_base_mixer },
3724 .init_verbs = { alc880_volume_init_verbs,
3725 alc880_pin_w810_init_verbs,
3726 alc880_gpio2_init_verbs },
3727 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3728 .dac_nids = alc880_w810_dac_nids,
3729 .dig_out_nid = ALC880_DIGOUT_NID,
3730 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3731 .channel_mode = alc880_w810_modes,
3732 .input_mux = &alc880_capture_source,
3735 .mixers = { alc880_z71v_mixer },
3736 .init_verbs = { alc880_volume_init_verbs,
3737 alc880_pin_z71v_init_verbs },
3738 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3739 .dac_nids = alc880_z71v_dac_nids,
3740 .dig_out_nid = ALC880_DIGOUT_NID,
3742 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3743 .channel_mode = alc880_2_jack_modes,
3744 .input_mux = &alc880_capture_source,
3747 .mixers = { alc880_f1734_mixer },
3748 .init_verbs = { alc880_volume_init_verbs,
3749 alc880_pin_f1734_init_verbs },
3750 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3751 .dac_nids = alc880_f1734_dac_nids,
3753 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3754 .channel_mode = alc880_2_jack_modes,
3755 .input_mux = &alc880_f1734_capture_source,
3756 .unsol_event = alc880_uniwill_p53_unsol_event,
3757 .init_hook = alc880_uniwill_p53_hp_automute,
3760 .mixers = { alc880_asus_mixer },
3761 .init_verbs = { alc880_volume_init_verbs,
3762 alc880_pin_asus_init_verbs,
3763 alc880_gpio1_init_verbs },
3764 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3765 .dac_nids = alc880_asus_dac_nids,
3766 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3767 .channel_mode = alc880_asus_modes,
3769 .input_mux = &alc880_capture_source,
3771 [ALC880_ASUS_DIG] = {
3772 .mixers = { alc880_asus_mixer },
3773 .init_verbs = { alc880_volume_init_verbs,
3774 alc880_pin_asus_init_verbs,
3775 alc880_gpio1_init_verbs },
3776 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3777 .dac_nids = alc880_asus_dac_nids,
3778 .dig_out_nid = ALC880_DIGOUT_NID,
3779 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3780 .channel_mode = alc880_asus_modes,
3782 .input_mux = &alc880_capture_source,
3784 [ALC880_ASUS_DIG2] = {
3785 .mixers = { alc880_asus_mixer },
3786 .init_verbs = { alc880_volume_init_verbs,
3787 alc880_pin_asus_init_verbs,
3788 alc880_gpio2_init_verbs }, /* use GPIO2 */
3789 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3790 .dac_nids = alc880_asus_dac_nids,
3791 .dig_out_nid = ALC880_DIGOUT_NID,
3792 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3793 .channel_mode = alc880_asus_modes,
3795 .input_mux = &alc880_capture_source,
3797 [ALC880_ASUS_W1V] = {
3798 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3799 .init_verbs = { alc880_volume_init_verbs,
3800 alc880_pin_asus_init_verbs,
3801 alc880_gpio1_init_verbs },
3802 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3803 .dac_nids = alc880_asus_dac_nids,
3804 .dig_out_nid = ALC880_DIGOUT_NID,
3805 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3806 .channel_mode = alc880_asus_modes,
3808 .input_mux = &alc880_capture_source,
3810 [ALC880_UNIWILL_DIG] = {
3811 .mixers = { alc880_asus_mixer },
3812 .init_verbs = { alc880_volume_init_verbs,
3813 alc880_pin_asus_init_verbs },
3814 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3815 .dac_nids = alc880_asus_dac_nids,
3816 .dig_out_nid = ALC880_DIGOUT_NID,
3817 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3818 .channel_mode = alc880_asus_modes,
3820 .input_mux = &alc880_capture_source,
3822 [ALC880_UNIWILL] = {
3823 .mixers = { alc880_uniwill_mixer },
3824 .init_verbs = { alc880_volume_init_verbs,
3825 alc880_uniwill_init_verbs },
3826 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3827 .dac_nids = alc880_asus_dac_nids,
3828 .dig_out_nid = ALC880_DIGOUT_NID,
3829 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3830 .channel_mode = alc880_threestack_modes,
3832 .input_mux = &alc880_capture_source,
3833 .unsol_event = alc880_uniwill_unsol_event,
3834 .init_hook = alc880_uniwill_automute,
3836 [ALC880_UNIWILL_P53] = {
3837 .mixers = { alc880_uniwill_p53_mixer },
3838 .init_verbs = { alc880_volume_init_verbs,
3839 alc880_uniwill_p53_init_verbs },
3840 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3841 .dac_nids = alc880_asus_dac_nids,
3842 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3843 .channel_mode = alc880_threestack_modes,
3844 .input_mux = &alc880_capture_source,
3845 .unsol_event = alc880_uniwill_p53_unsol_event,
3846 .init_hook = alc880_uniwill_p53_hp_automute,
3848 [ALC880_FUJITSU] = {
3849 .mixers = { alc880_fujitsu_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 alc_set_input_pin(codec, nid, i);
4231 if (nid != ALC880_PIN_CD_NID &&
4232 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4233 snd_hda_codec_write(codec, nid, 0,
4234 AC_VERB_SET_AMP_GAIN_MUTE,
4240 /* parse the BIOS configuration and set up the alc_spec */
4241 /* return 1 if successful, 0 if the proper config is not found,
4242 * or a negative error code
4244 static int alc880_parse_auto_config(struct hda_codec *codec)
4246 struct alc_spec *spec = codec->spec;
4248 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4250 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4254 if (!spec->autocfg.line_outs)
4255 return 0; /* can't find valid BIOS pin config */
4257 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4260 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4263 err = alc880_auto_create_extra_out(spec,
4264 spec->autocfg.speaker_pins[0],
4268 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4272 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4276 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4278 /* check multiple SPDIF-out (for recent codecs) */
4279 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4281 err = snd_hda_get_connections(codec,
4282 spec->autocfg.dig_out_pins[i],
4287 spec->multiout.dig_out_nid = dig_nid;
4289 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4290 spec->slave_dig_outs[i - 1] = dig_nid;
4291 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4295 if (spec->autocfg.dig_in_pin)
4296 spec->dig_in_nid = ALC880_DIGIN_NID;
4298 if (spec->kctls.list)
4299 add_mixer(spec, spec->kctls.list);
4301 add_verb(spec, alc880_volume_init_verbs);
4303 spec->num_mux_defs = 1;
4304 spec->input_mux = &spec->private_imux[0];
4309 /* additional initialization for auto-configuration model */
4310 static void alc880_auto_init(struct hda_codec *codec)
4312 struct alc_spec *spec = codec->spec;
4313 alc880_auto_init_multi_out(codec);
4314 alc880_auto_init_extra_out(codec);
4315 alc880_auto_init_analog_input(codec);
4316 if (spec->unsol_event)
4317 alc_inithook(codec);
4320 static void set_capture_mixer(struct alc_spec *spec)
4322 static struct snd_kcontrol_new *caps[2][3] = {
4323 { alc_capture_mixer_nosrc1,
4324 alc_capture_mixer_nosrc2,
4325 alc_capture_mixer_nosrc3 },
4326 { alc_capture_mixer1,
4328 alc_capture_mixer3 },
4330 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4332 if (spec->input_mux && spec->input_mux->num_items > 1)
4336 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4340 #define set_beep_amp(spec, nid, idx, dir) \
4341 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4344 * OK, here we have finally the patch for ALC880
4347 static int patch_alc880(struct hda_codec *codec)
4349 struct alc_spec *spec;
4353 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4359 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4362 if (board_config < 0) {
4363 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4364 "trying auto-probe from BIOS...\n");
4365 board_config = ALC880_AUTO;
4368 if (board_config == ALC880_AUTO) {
4369 /* automatic parse from the BIOS config */
4370 err = alc880_parse_auto_config(codec);
4376 "hda_codec: Cannot set up configuration "
4377 "from BIOS. Using 3-stack mode...\n");
4378 board_config = ALC880_3ST;
4382 err = snd_hda_attach_beep_device(codec, 0x1);
4388 if (board_config != ALC880_AUTO)
4389 setup_preset(spec, &alc880_presets[board_config]);
4391 spec->stream_name_analog = "ALC880 Analog";
4392 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4393 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4394 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4396 spec->stream_name_digital = "ALC880 Digital";
4397 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4398 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4400 if (!spec->adc_nids && spec->input_mux) {
4401 /* check whether NID 0x07 is valid */
4402 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4404 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4405 if (wcap != AC_WID_AUD_IN) {
4406 spec->adc_nids = alc880_adc_nids_alt;
4407 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4409 spec->adc_nids = alc880_adc_nids;
4410 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4413 set_capture_mixer(spec);
4414 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4416 spec->vmaster_nid = 0x0c;
4418 codec->patch_ops = alc_patch_ops;
4419 if (board_config == ALC880_AUTO)
4420 spec->init_hook = alc880_auto_init;
4421 #ifdef CONFIG_SND_HDA_POWER_SAVE
4422 if (!spec->loopback.amplist)
4423 spec->loopback.amplist = alc880_loopbacks;
4425 codec->proc_widget_hook = print_realtek_coef;
4435 static hda_nid_t alc260_dac_nids[1] = {
4440 static hda_nid_t alc260_adc_nids[1] = {
4445 static hda_nid_t alc260_adc_nids_alt[1] = {
4450 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4451 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4453 static hda_nid_t alc260_dual_adc_nids[2] = {
4458 #define ALC260_DIGOUT_NID 0x03
4459 #define ALC260_DIGIN_NID 0x06
4461 static struct hda_input_mux alc260_capture_source = {
4465 { "Front Mic", 0x1 },
4471 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4472 * headphone jack and the internal CD lines since these are the only pins at
4473 * which audio can appear. For flexibility, also allow the option of
4474 * recording the mixer output on the second ADC (ADC0 doesn't have a
4475 * connection to the mixer output).
4477 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4481 { "Mic/Line", 0x0 },
4483 { "Headphone", 0x2 },
4489 { "Mic/Line", 0x0 },
4491 { "Headphone", 0x2 },
4498 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4499 * the Fujitsu S702x, but jacks are marked differently.
4501 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4508 { "Headphone", 0x5 },
4517 { "Headphone", 0x6 },
4523 /* Maxdata Favorit 100XS */
4524 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4528 { "Line/Mic", 0x0 },
4535 { "Line/Mic", 0x0 },
4543 * This is just place-holder, so there's something for alc_build_pcms to look
4544 * at when it calculates the maximum number of channels. ALC260 has no mixer
4545 * element which allows changing the channel mode, so the verb list is
4548 static struct hda_channel_mode alc260_modes[1] = {
4553 /* Mixer combinations
4555 * basic: base_output + input + pc_beep + capture
4556 * HP: base_output + input + capture_alt
4557 * HP_3013: hp_3013 + input + capture
4558 * fujitsu: fujitsu + capture
4559 * acer: acer + capture
4562 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4563 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4564 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4565 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4566 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4567 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4568 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4572 static struct snd_kcontrol_new alc260_input_mixer[] = {
4573 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4574 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4575 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4576 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4577 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4578 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4579 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4580 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4584 /* update HP, line and mono out pins according to the master switch */
4585 static void alc260_hp_master_update(struct hda_codec *codec,
4586 hda_nid_t hp, hda_nid_t line,
4589 struct alc_spec *spec = codec->spec;
4590 unsigned int val = spec->master_sw ? PIN_HP : 0;
4591 /* change HP and line-out pins */
4592 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4594 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4596 /* mono (speaker) depending on the HP jack sense */
4597 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4598 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4602 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4603 struct snd_ctl_elem_value *ucontrol)
4605 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4606 struct alc_spec *spec = codec->spec;
4607 *ucontrol->value.integer.value = spec->master_sw;
4611 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4612 struct snd_ctl_elem_value *ucontrol)
4614 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4615 struct alc_spec *spec = codec->spec;
4616 int val = !!*ucontrol->value.integer.value;
4617 hda_nid_t hp, line, mono;
4619 if (val == spec->master_sw)
4621 spec->master_sw = val;
4622 hp = (kcontrol->private_value >> 16) & 0xff;
4623 line = (kcontrol->private_value >> 8) & 0xff;
4624 mono = kcontrol->private_value & 0xff;
4625 alc260_hp_master_update(codec, hp, line, mono);
4629 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4631 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4632 .name = "Master Playback Switch",
4633 .info = snd_ctl_boolean_mono_info,
4634 .get = alc260_hp_master_sw_get,
4635 .put = alc260_hp_master_sw_put,
4636 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4638 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4639 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4640 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4641 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4642 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4644 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4648 static struct hda_verb alc260_hp_unsol_verbs[] = {
4649 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4653 static void alc260_hp_automute(struct hda_codec *codec)
4655 struct alc_spec *spec = codec->spec;
4656 unsigned int present;
4658 present = snd_hda_codec_read(codec, 0x10, 0,
4659 AC_VERB_GET_PIN_SENSE, 0);
4660 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4661 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4664 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4666 if ((res >> 26) == ALC880_HP_EVENT)
4667 alc260_hp_automute(codec);
4670 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4672 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4673 .name = "Master Playback Switch",
4674 .info = snd_ctl_boolean_mono_info,
4675 .get = alc260_hp_master_sw_get,
4676 .put = alc260_hp_master_sw_put,
4677 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4679 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4680 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4681 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4682 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4683 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4684 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4685 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4686 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4690 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4691 .ops = &snd_hda_bind_vol,
4693 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4694 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4695 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4700 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4701 .ops = &snd_hda_bind_sw,
4703 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4704 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4709 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4710 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4711 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4712 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4713 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4717 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4718 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4722 static void alc260_hp_3013_automute(struct hda_codec *codec)
4724 struct alc_spec *spec = codec->spec;
4725 unsigned int present;
4727 present = snd_hda_codec_read(codec, 0x15, 0,
4728 AC_VERB_GET_PIN_SENSE, 0);
4729 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4730 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4733 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4736 if ((res >> 26) == ALC880_HP_EVENT)
4737 alc260_hp_3013_automute(codec);
4740 static void alc260_hp_3012_automute(struct hda_codec *codec)
4742 unsigned int present, bits;
4744 present = snd_hda_codec_read(codec, 0x10, 0,
4745 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4747 bits = present ? 0 : PIN_OUT;
4748 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4750 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4752 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4756 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4759 if ((res >> 26) == ALC880_HP_EVENT)
4760 alc260_hp_3012_automute(codec);
4763 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4764 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4766 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4767 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4768 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4769 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4770 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4771 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4772 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4773 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4774 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4775 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4776 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4780 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4781 * versions of the ALC260 don't act on requests to enable mic bias from NID
4782 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4783 * datasheet doesn't mention this restriction. At this stage it's not clear
4784 * whether this behaviour is intentional or is a hardware bug in chip
4785 * revisions available in early 2006. Therefore for now allow the
4786 * "Headphone Jack Mode" control to span all choices, but if it turns out
4787 * that the lack of mic bias for this NID is intentional we could change the
4788 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4790 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4791 * don't appear to make the mic bias available from the "line" jack, even
4792 * though the NID used for this jack (0x14) can supply it. The theory is
4793 * that perhaps Acer have included blocking capacitors between the ALC260
4794 * and the output jack. If this turns out to be the case for all such
4795 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4796 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4798 * The C20x Tablet series have a mono internal speaker which is controlled
4799 * via the chip's Mono sum widget and pin complex, so include the necessary
4800 * controls for such models. On models without a "mono speaker" the control
4801 * won't do anything.
4803 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4804 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4805 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4806 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4807 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4809 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4811 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4812 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4814 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4815 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4816 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4817 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4818 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4822 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
4824 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
4825 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4826 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4827 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4828 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4829 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4830 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4834 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4835 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4837 static struct snd_kcontrol_new alc260_will_mixer[] = {
4838 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4839 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4841 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4842 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4843 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4844 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4845 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4846 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4847 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4851 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4852 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4854 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4855 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4856 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4858 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4859 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4860 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4861 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4862 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4863 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4864 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4869 * initialization verbs
4871 static struct hda_verb alc260_init_verbs[] = {
4872 /* Line In pin widget for input */
4873 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4874 /* CD pin widget for input */
4875 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4876 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4877 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4878 /* Mic2 (front panel) pin widget for input and vref at 80% */
4879 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4880 /* LINE-2 is used for line-out in rear */
4881 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4882 /* select line-out */
4883 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4885 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4887 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4889 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4890 /* mute capture amp left and right */
4891 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4892 /* set connection select to line in (default select for this ADC) */
4893 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4894 /* mute capture amp left and right */
4895 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4896 /* set connection select to line in (default select for this ADC) */
4897 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4898 /* set vol=0 Line-Out mixer amp left and right */
4899 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4900 /* unmute pin widget amp left and right (no gain on this amp) */
4901 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4902 /* set vol=0 HP mixer amp left and right */
4903 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4904 /* unmute pin widget amp left and right (no gain on this amp) */
4905 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4906 /* set vol=0 Mono mixer amp left and right */
4907 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4908 /* unmute pin widget amp left and right (no gain on this amp) */
4909 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4910 /* unmute LINE-2 out pin */
4911 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4912 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4915 /* mute analog inputs */
4916 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4917 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4918 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4919 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4920 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4921 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4922 /* mute Front out path */
4923 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4924 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4925 /* mute Headphone out path */
4926 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4927 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4928 /* mute Mono out path */
4929 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4930 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4934 #if 0 /* should be identical with alc260_init_verbs? */
4935 static struct hda_verb alc260_hp_init_verbs[] = {
4936 /* Headphone and output */
4937 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4939 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4940 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4941 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4942 /* Mic2 (front panel) pin widget for input and vref at 80% */
4943 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4944 /* Line In pin widget for input */
4945 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4946 /* Line-2 pin widget for output */
4947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4948 /* CD pin widget for input */
4949 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4950 /* unmute amp left and right */
4951 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4952 /* set connection select to line in (default select for this ADC) */
4953 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4954 /* unmute Line-Out mixer amp left and right (volume = 0) */
4955 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4956 /* mute pin widget amp left and right (no gain on this amp) */
4957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4958 /* unmute HP mixer amp left and right (volume = 0) */
4959 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4960 /* mute pin widget amp left and right (no gain on this amp) */
4961 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4962 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4965 /* mute analog inputs */
4966 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4967 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4968 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4969 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4970 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4971 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4972 /* Unmute Front out path */
4973 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4974 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4975 /* Unmute Headphone out path */
4976 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4977 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4978 /* Unmute Mono out path */
4979 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4980 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4985 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4986 /* Line out and output */
4987 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4989 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4990 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4991 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4992 /* Mic2 (front panel) pin widget for input and vref at 80% */
4993 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4994 /* Line In pin widget for input */
4995 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4996 /* Headphone pin widget for output */
4997 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4998 /* CD pin widget for input */
4999 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5000 /* unmute amp left and right */
5001 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5002 /* set connection select to line in (default select for this ADC) */
5003 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5004 /* unmute Line-Out mixer amp left and right (volume = 0) */
5005 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5006 /* mute pin widget amp left and right (no gain on this amp) */
5007 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5008 /* unmute HP mixer amp left and right (volume = 0) */
5009 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5010 /* mute pin widget amp left and right (no gain on this amp) */
5011 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5012 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5015 /* mute analog inputs */
5016 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5017 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5018 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5019 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5020 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5021 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5022 /* Unmute Front out path */
5023 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5024 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5025 /* Unmute Headphone out path */
5026 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5027 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5028 /* Unmute Mono out path */
5029 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5030 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5034 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5035 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5036 * audio = 0x16, internal speaker = 0x10.
5038 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5039 /* Disable all GPIOs */
5040 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5041 /* Internal speaker is connected to headphone pin */
5042 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5043 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5044 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5045 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5046 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5047 /* Ensure all other unused pins are disabled and muted. */
5048 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5049 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5050 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5051 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5052 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5053 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5055 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5057 /* Disable digital (SPDIF) pins */
5058 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5059 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5061 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5062 * when acting as an output.
5064 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5066 /* Start with output sum widgets muted and their output gains at min */
5067 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5068 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5069 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5070 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5071 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5072 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5073 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5074 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5075 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5077 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5078 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5079 /* Unmute Line1 pin widget output buffer since it starts as an output.
5080 * If the pin mode is changed by the user the pin mode control will
5081 * take care of enabling the pin's input/output buffers as needed.
5082 * Therefore there's no need to enable the input buffer at this
5085 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5086 /* Unmute input buffer of pin widget used for Line-in (no equiv
5089 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5091 /* Mute capture amp left and right */
5092 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5093 /* Set ADC connection select to match default mixer setting - line
5096 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5098 /* Do the same for the second ADC: mute capture input amp and
5099 * set ADC connection to line in (on mic1 pin)
5101 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5102 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5104 /* Mute all inputs to mixer widget (even unconnected ones) */
5105 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5106 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5107 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5108 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5109 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5110 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5111 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5117 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5118 * similar laptops (adapted from Fujitsu init verbs).
5120 static struct hda_verb alc260_acer_init_verbs[] = {
5121 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5122 * the headphone jack. Turn this on and rely on the standard mute
5123 * methods whenever the user wants to turn these outputs off.
5125 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5126 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5127 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5128 /* Internal speaker/Headphone jack is connected to Line-out pin */
5129 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5130 /* Internal microphone/Mic jack is connected to Mic1 pin */
5131 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5132 /* Line In jack is connected to Line1 pin */
5133 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5134 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5135 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5136 /* Ensure all other unused pins are disabled and muted. */
5137 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5138 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5139 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5140 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5141 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5142 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5143 /* Disable digital (SPDIF) pins */
5144 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5145 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5147 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5148 * bus when acting as outputs.
5150 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5151 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5153 /* Start with output sum widgets muted and their output gains at min */
5154 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5155 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5156 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5157 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5158 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5159 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5160 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5161 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5162 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5164 /* Unmute Line-out pin widget amp left and right
5165 * (no equiv mixer ctrl)
5167 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5168 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5169 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5170 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5171 * inputs. If the pin mode is changed by the user the pin mode control
5172 * will take care of enabling the pin's input/output buffers as needed.
5173 * Therefore there's no need to enable the input buffer at this
5176 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5177 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5179 /* Mute capture amp left and right */
5180 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5181 /* Set ADC connection select to match default mixer setting - mic
5184 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5186 /* Do similar with the second ADC: mute capture input amp and
5187 * set ADC connection to mic to match ALSA's default state.
5189 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5190 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5192 /* Mute all inputs to mixer widget (even unconnected ones) */
5193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5194 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5195 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5196 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5197 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5198 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5199 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5200 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5205 /* Initialisation sequence for Maxdata Favorit 100XS
5206 * (adapted from Acer init verbs).
5208 static struct hda_verb alc260_favorit100_init_verbs[] = {
5209 /* GPIO 0 enables the output jack.
5210 * Turn this on and rely on the standard mute
5211 * methods whenever the user wants to turn these outputs off.
5213 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5214 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5215 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5216 /* Line/Mic input jack is connected to Mic1 pin */
5217 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5218 /* Ensure all other unused pins are disabled and muted. */
5219 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5220 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5221 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5222 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5223 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5224 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5225 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5226 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5227 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5228 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5229 /* Disable digital (SPDIF) pins */
5230 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5231 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5233 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5234 * bus when acting as outputs.
5236 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5237 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5239 /* Start with output sum widgets muted and their output gains at min */
5240 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5241 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5242 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5243 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5245 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5246 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5247 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5248 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5250 /* Unmute Line-out pin widget amp left and right
5251 * (no equiv mixer ctrl)
5253 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5254 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5255 * inputs. If the pin mode is changed by the user the pin mode control
5256 * will take care of enabling the pin's input/output buffers as needed.
5257 * Therefore there's no need to enable the input buffer at this
5260 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5262 /* Mute capture amp left and right */
5263 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5264 /* Set ADC connection select to match default mixer setting - mic
5267 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5269 /* Do similar with the second ADC: mute capture input amp and
5270 * set ADC connection to mic to match ALSA's default state.
5272 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5273 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5275 /* Mute all inputs to mixer widget (even unconnected ones) */
5276 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5277 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5278 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5280 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5281 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5282 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5283 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5288 static struct hda_verb alc260_will_verbs[] = {
5289 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5290 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5291 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5292 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5293 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5294 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5298 static struct hda_verb alc260_replacer_672v_verbs[] = {
5299 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5300 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5301 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5303 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5304 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5305 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5307 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5311 /* toggle speaker-output according to the hp-jack state */
5312 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5314 unsigned int present;
5316 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5317 present = snd_hda_codec_read(codec, 0x0f, 0,
5318 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5320 snd_hda_codec_write_cache(codec, 0x01, 0,
5321 AC_VERB_SET_GPIO_DATA, 1);
5322 snd_hda_codec_write_cache(codec, 0x0f, 0,
5323 AC_VERB_SET_PIN_WIDGET_CONTROL,
5326 snd_hda_codec_write_cache(codec, 0x01, 0,
5327 AC_VERB_SET_GPIO_DATA, 0);
5328 snd_hda_codec_write_cache(codec, 0x0f, 0,
5329 AC_VERB_SET_PIN_WIDGET_CONTROL,
5334 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5337 if ((res >> 26) == ALC880_HP_EVENT)
5338 alc260_replacer_672v_automute(codec);
5341 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5342 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5343 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5344 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5345 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5346 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5347 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5348 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5349 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5350 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5351 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5355 /* Test configuration for debugging, modelled after the ALC880 test
5358 #ifdef CONFIG_SND_DEBUG
5359 static hda_nid_t alc260_test_dac_nids[1] = {
5362 static hda_nid_t alc260_test_adc_nids[2] = {
5365 /* For testing the ALC260, each input MUX needs its own definition since
5366 * the signal assignments are different. This assumes that the first ADC
5369 static struct hda_input_mux alc260_test_capture_sources[2] = {
5373 { "MIC1 pin", 0x0 },
5374 { "MIC2 pin", 0x1 },
5375 { "LINE1 pin", 0x2 },
5376 { "LINE2 pin", 0x3 },
5378 { "LINE-OUT pin", 0x5 },
5379 { "HP-OUT pin", 0x6 },
5385 { "MIC1 pin", 0x0 },
5386 { "MIC2 pin", 0x1 },
5387 { "LINE1 pin", 0x2 },
5388 { "LINE2 pin", 0x3 },
5391 { "LINE-OUT pin", 0x6 },
5392 { "HP-OUT pin", 0x7 },
5396 static struct snd_kcontrol_new alc260_test_mixer[] = {
5397 /* Output driver widgets */
5398 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5399 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5400 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5401 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5402 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5403 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5405 /* Modes for retasking pin widgets
5406 * Note: the ALC260 doesn't seem to act on requests to enable mic
5407 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5408 * mention this restriction. At this stage it's not clear whether
5409 * this behaviour is intentional or is a hardware bug in chip
5410 * revisions available at least up until early 2006. Therefore for
5411 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5412 * choices, but if it turns out that the lack of mic bias for these
5413 * NIDs is intentional we could change their modes from
5414 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5416 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5417 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5418 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5419 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5420 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5421 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5423 /* Loopback mixer controls */
5424 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5425 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5426 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5427 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5428 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5429 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5430 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5431 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5432 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5433 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5434 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5435 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5436 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5437 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5439 /* Controls for GPIO pins, assuming they are configured as outputs */
5440 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5441 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5442 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5443 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5445 /* Switches to allow the digital IO pins to be enabled. The datasheet
5446 * is ambigious as to which NID is which; testing on laptops which
5447 * make this output available should provide clarification.
5449 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5450 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5452 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5453 * this output to turn on an external amplifier.
5455 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5456 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5460 static struct hda_verb alc260_test_init_verbs[] = {
5461 /* Enable all GPIOs as outputs with an initial value of 0 */
5462 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5463 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5464 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5466 /* Enable retasking pins as output, initially without power amp */
5467 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5468 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5469 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5470 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5471 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5472 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5474 /* Disable digital (SPDIF) pins initially, but users can enable
5475 * them via a mixer switch. In the case of SPDIF-out, this initverb
5476 * payload also sets the generation to 0, output to be in "consumer"
5477 * PCM format, copyright asserted, no pre-emphasis and no validity
5480 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5481 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5483 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5484 * OUT1 sum bus when acting as an output.
5486 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5487 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5488 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5489 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5491 /* Start with output sum widgets muted and their output gains at min */
5492 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5493 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5494 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5495 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5496 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5497 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5498 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5499 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5500 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5502 /* Unmute retasking pin widget output buffers since the default
5503 * state appears to be output. As the pin mode is changed by the
5504 * user the pin mode control will take care of enabling the pin's
5505 * input/output buffers as needed.
5507 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5508 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5509 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5510 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5511 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5512 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5513 /* Also unmute the mono-out pin widget */
5514 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5516 /* Mute capture amp left and right */
5517 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5518 /* Set ADC connection select to match default mixer setting (mic1
5521 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5523 /* Do the same for the second ADC: mute capture input amp and
5524 * set ADC connection to mic1 pin
5526 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5527 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5529 /* Mute all inputs to mixer widget (even unconnected ones) */
5530 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5531 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5532 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5533 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5534 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5536 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5537 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5543 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5544 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5546 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5547 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5550 * for BIOS auto-configuration
5553 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5554 const char *pfx, int *vol_bits)
5557 unsigned long vol_val, sw_val;
5561 if (nid >= 0x0f && nid < 0x11) {
5562 nid_vol = nid - 0x7;
5563 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5564 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5565 } else if (nid == 0x11) {
5566 nid_vol = nid - 0x7;
5567 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5568 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5569 } else if (nid >= 0x12 && nid <= 0x15) {
5571 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5572 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5576 if (!(*vol_bits & (1 << nid_vol))) {
5577 /* first control for the volume widget */
5578 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5579 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5582 *vol_bits |= (1 << nid_vol);
5584 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5585 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5591 /* add playback controls from the parsed DAC table */
5592 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5593 const struct auto_pin_cfg *cfg)
5599 spec->multiout.num_dacs = 1;
5600 spec->multiout.dac_nids = spec->private_dac_nids;
5601 spec->multiout.dac_nids[0] = 0x02;
5603 nid = cfg->line_out_pins[0];
5605 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5610 nid = cfg->speaker_pins[0];
5612 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5617 nid = cfg->hp_pins[0];
5619 err = alc260_add_playback_controls(spec, nid, "Headphone",
5627 /* create playback/capture controls for input pins */
5628 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5629 const struct auto_pin_cfg *cfg)
5631 struct hda_input_mux *imux = &spec->private_imux[0];
5634 for (i = 0; i < AUTO_PIN_LAST; i++) {
5635 if (cfg->input_pins[i] >= 0x12) {
5636 idx = cfg->input_pins[i] - 0x12;
5637 err = new_analog_input(spec, cfg->input_pins[i],
5638 auto_pin_cfg_labels[i], idx,
5642 imux->items[imux->num_items].label =
5643 auto_pin_cfg_labels[i];
5644 imux->items[imux->num_items].index = idx;
5647 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5648 idx = cfg->input_pins[i] - 0x09;
5649 err = new_analog_input(spec, cfg->input_pins[i],
5650 auto_pin_cfg_labels[i], idx,
5654 imux->items[imux->num_items].label =
5655 auto_pin_cfg_labels[i];
5656 imux->items[imux->num_items].index = idx;
5663 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5664 hda_nid_t nid, int pin_type,
5667 alc_set_pin_output(codec, nid, pin_type);
5668 /* need the manual connection? */
5670 int idx = nid - 0x12;
5671 snd_hda_codec_write(codec, idx + 0x0b, 0,
5672 AC_VERB_SET_CONNECT_SEL, sel_idx);
5676 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5678 struct alc_spec *spec = codec->spec;
5681 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5682 nid = spec->autocfg.line_out_pins[0];
5684 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5685 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5688 nid = spec->autocfg.speaker_pins[0];
5690 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5692 nid = spec->autocfg.hp_pins[0];
5694 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5697 #define ALC260_PIN_CD_NID 0x16
5698 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5700 struct alc_spec *spec = codec->spec;
5703 for (i = 0; i < AUTO_PIN_LAST; i++) {
5704 hda_nid_t nid = spec->autocfg.input_pins[i];
5706 alc_set_input_pin(codec, nid, i);
5707 if (nid != ALC260_PIN_CD_NID &&
5708 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5709 snd_hda_codec_write(codec, nid, 0,
5710 AC_VERB_SET_AMP_GAIN_MUTE,
5717 * generic initialization of ADC, input mixers and output mixers
5719 static struct hda_verb alc260_volume_init_verbs[] = {
5721 * Unmute ADC0-1 and set the default input to mic-in
5723 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5724 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5725 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5726 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5728 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5730 * Note: PASD motherboards uses the Line In 2 as the input for
5731 * front panel mic (mic 2)
5733 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5734 /* mute analog inputs */
5735 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5736 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5737 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5738 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5739 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5742 * Set up output mixers (0x08 - 0x0a)
5744 /* set vol=0 to output mixers */
5745 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5746 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5747 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5748 /* set up input amps for analog loopback */
5749 /* Amp Indices: DAC = 0, mixer = 1 */
5750 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5751 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5752 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5753 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5754 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5755 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5760 static int alc260_parse_auto_config(struct hda_codec *codec)
5762 struct alc_spec *spec = codec->spec;
5764 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5766 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5770 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5773 if (!spec->kctls.list)
5774 return 0; /* can't find valid BIOS pin config */
5775 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5779 spec->multiout.max_channels = 2;
5781 if (spec->autocfg.dig_outs)
5782 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5783 if (spec->kctls.list)
5784 add_mixer(spec, spec->kctls.list);
5786 add_verb(spec, alc260_volume_init_verbs);
5788 spec->num_mux_defs = 1;
5789 spec->input_mux = &spec->private_imux[0];
5794 /* additional initialization for auto-configuration model */
5795 static void alc260_auto_init(struct hda_codec *codec)
5797 struct alc_spec *spec = codec->spec;
5798 alc260_auto_init_multi_out(codec);
5799 alc260_auto_init_analog_input(codec);
5800 if (spec->unsol_event)
5801 alc_inithook(codec);
5804 #ifdef CONFIG_SND_HDA_POWER_SAVE
5805 static struct hda_amp_list alc260_loopbacks[] = {
5806 { 0x07, HDA_INPUT, 0 },
5807 { 0x07, HDA_INPUT, 1 },
5808 { 0x07, HDA_INPUT, 2 },
5809 { 0x07, HDA_INPUT, 3 },
5810 { 0x07, HDA_INPUT, 4 },
5816 * ALC260 configurations
5818 static const char *alc260_models[ALC260_MODEL_LAST] = {
5819 [ALC260_BASIC] = "basic",
5821 [ALC260_HP_3013] = "hp-3013",
5822 [ALC260_HP_DC7600] = "hp-dc7600",
5823 [ALC260_FUJITSU_S702X] = "fujitsu",
5824 [ALC260_ACER] = "acer",
5825 [ALC260_WILL] = "will",
5826 [ALC260_REPLACER_672V] = "replacer",
5827 [ALC260_FAVORIT100] = "favorit100",
5828 #ifdef CONFIG_SND_DEBUG
5829 [ALC260_TEST] = "test",
5831 [ALC260_AUTO] = "auto",
5834 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5835 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5836 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5837 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
5838 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5839 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5840 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5841 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5842 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5843 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5844 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5845 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5846 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5847 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5848 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5849 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5850 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5851 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5852 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5853 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5857 static struct alc_config_preset alc260_presets[] = {
5859 .mixers = { alc260_base_output_mixer,
5860 alc260_input_mixer },
5861 .init_verbs = { alc260_init_verbs },
5862 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5863 .dac_nids = alc260_dac_nids,
5864 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5865 .adc_nids = alc260_adc_nids,
5866 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5867 .channel_mode = alc260_modes,
5868 .input_mux = &alc260_capture_source,
5871 .mixers = { alc260_hp_output_mixer,
5872 alc260_input_mixer },
5873 .init_verbs = { alc260_init_verbs,
5874 alc260_hp_unsol_verbs },
5875 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5876 .dac_nids = alc260_dac_nids,
5877 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5878 .adc_nids = alc260_adc_nids_alt,
5879 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5880 .channel_mode = alc260_modes,
5881 .input_mux = &alc260_capture_source,
5882 .unsol_event = alc260_hp_unsol_event,
5883 .init_hook = alc260_hp_automute,
5885 [ALC260_HP_DC7600] = {
5886 .mixers = { alc260_hp_dc7600_mixer,
5887 alc260_input_mixer },
5888 .init_verbs = { alc260_init_verbs,
5889 alc260_hp_dc7600_verbs },
5890 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5891 .dac_nids = alc260_dac_nids,
5892 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5893 .adc_nids = alc260_adc_nids_alt,
5894 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5895 .channel_mode = alc260_modes,
5896 .input_mux = &alc260_capture_source,
5897 .unsol_event = alc260_hp_3012_unsol_event,
5898 .init_hook = alc260_hp_3012_automute,
5900 [ALC260_HP_3013] = {
5901 .mixers = { alc260_hp_3013_mixer,
5902 alc260_input_mixer },
5903 .init_verbs = { alc260_hp_3013_init_verbs,
5904 alc260_hp_3013_unsol_verbs },
5905 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5906 .dac_nids = alc260_dac_nids,
5907 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5908 .adc_nids = alc260_adc_nids_alt,
5909 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5910 .channel_mode = alc260_modes,
5911 .input_mux = &alc260_capture_source,
5912 .unsol_event = alc260_hp_3013_unsol_event,
5913 .init_hook = alc260_hp_3013_automute,
5915 [ALC260_FUJITSU_S702X] = {
5916 .mixers = { alc260_fujitsu_mixer },
5917 .init_verbs = { alc260_fujitsu_init_verbs },
5918 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5919 .dac_nids = alc260_dac_nids,
5920 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5921 .adc_nids = alc260_dual_adc_nids,
5922 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5923 .channel_mode = alc260_modes,
5924 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5925 .input_mux = alc260_fujitsu_capture_sources,
5928 .mixers = { alc260_acer_mixer },
5929 .init_verbs = { alc260_acer_init_verbs },
5930 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5931 .dac_nids = alc260_dac_nids,
5932 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5933 .adc_nids = alc260_dual_adc_nids,
5934 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5935 .channel_mode = alc260_modes,
5936 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5937 .input_mux = alc260_acer_capture_sources,
5939 [ALC260_FAVORIT100] = {
5940 .mixers = { alc260_favorit100_mixer },
5941 .init_verbs = { alc260_favorit100_init_verbs },
5942 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5943 .dac_nids = alc260_dac_nids,
5944 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5945 .adc_nids = alc260_dual_adc_nids,
5946 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5947 .channel_mode = alc260_modes,
5948 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
5949 .input_mux = alc260_favorit100_capture_sources,
5952 .mixers = { alc260_will_mixer },
5953 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5954 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5955 .dac_nids = alc260_dac_nids,
5956 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5957 .adc_nids = alc260_adc_nids,
5958 .dig_out_nid = ALC260_DIGOUT_NID,
5959 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5960 .channel_mode = alc260_modes,
5961 .input_mux = &alc260_capture_source,
5963 [ALC260_REPLACER_672V] = {
5964 .mixers = { alc260_replacer_672v_mixer },
5965 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5966 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5967 .dac_nids = alc260_dac_nids,
5968 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5969 .adc_nids = alc260_adc_nids,
5970 .dig_out_nid = ALC260_DIGOUT_NID,
5971 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5972 .channel_mode = alc260_modes,
5973 .input_mux = &alc260_capture_source,
5974 .unsol_event = alc260_replacer_672v_unsol_event,
5975 .init_hook = alc260_replacer_672v_automute,
5977 #ifdef CONFIG_SND_DEBUG
5979 .mixers = { alc260_test_mixer },
5980 .init_verbs = { alc260_test_init_verbs },
5981 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5982 .dac_nids = alc260_test_dac_nids,
5983 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5984 .adc_nids = alc260_test_adc_nids,
5985 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5986 .channel_mode = alc260_modes,
5987 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5988 .input_mux = alc260_test_capture_sources,
5993 static int patch_alc260(struct hda_codec *codec)
5995 struct alc_spec *spec;
5996 int err, board_config;
5998 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6004 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6007 if (board_config < 0) {
6008 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
6009 "trying auto-probe from BIOS...\n");
6010 board_config = ALC260_AUTO;
6013 if (board_config == ALC260_AUTO) {
6014 /* automatic parse from the BIOS config */
6015 err = alc260_parse_auto_config(codec);
6021 "hda_codec: Cannot set up configuration "
6022 "from BIOS. Using base mode...\n");
6023 board_config = ALC260_BASIC;
6027 err = snd_hda_attach_beep_device(codec, 0x1);
6033 if (board_config != ALC260_AUTO)
6034 setup_preset(spec, &alc260_presets[board_config]);
6036 spec->stream_name_analog = "ALC260 Analog";
6037 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6038 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6040 spec->stream_name_digital = "ALC260 Digital";
6041 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6042 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6044 if (!spec->adc_nids && spec->input_mux) {
6045 /* check whether NID 0x04 is valid */
6046 unsigned int wcap = get_wcaps(codec, 0x04);
6047 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6049 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6050 spec->adc_nids = alc260_adc_nids_alt;
6051 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6053 spec->adc_nids = alc260_adc_nids;
6054 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6057 set_capture_mixer(spec);
6058 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6060 spec->vmaster_nid = 0x08;
6062 codec->patch_ops = alc_patch_ops;
6063 if (board_config == ALC260_AUTO)
6064 spec->init_hook = alc260_auto_init;
6065 #ifdef CONFIG_SND_HDA_POWER_SAVE
6066 if (!spec->loopback.amplist)
6067 spec->loopback.amplist = alc260_loopbacks;
6069 codec->proc_widget_hook = print_realtek_coef;
6078 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6079 * configuration. Each pin widget can choose any input DACs and a mixer.
6080 * Each ADC is connected from a mixer of all inputs. This makes possible
6081 * 6-channel independent captures.
6083 * In addition, an independent DAC for the multi-playback (not used in this
6086 #define ALC882_DIGOUT_NID 0x06
6087 #define ALC882_DIGIN_NID 0x0a
6089 static struct hda_channel_mode alc882_ch_modes[1] = {
6093 static hda_nid_t alc882_dac_nids[4] = {
6094 /* front, rear, clfe, rear_surr */
6095 0x02, 0x03, 0x04, 0x05
6098 /* identical with ALC880 */
6099 #define alc882_adc_nids alc880_adc_nids
6100 #define alc882_adc_nids_alt alc880_adc_nids_alt
6102 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6103 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6106 /* FIXME: should be a matrix-type input source selection */
6108 static struct hda_input_mux alc882_capture_source = {
6112 { "Front Mic", 0x1 },
6120 static struct hda_verb alc882_3ST_ch2_init[] = {
6121 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6122 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6123 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6124 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6131 static struct hda_verb alc882_3ST_ch6_init[] = {
6132 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6133 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6134 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6135 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6136 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6137 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6141 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6142 { 2, alc882_3ST_ch2_init },
6143 { 6, alc882_3ST_ch6_init },
6149 static struct hda_verb alc882_sixstack_ch6_init[] = {
6150 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6151 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6152 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6153 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6160 static struct hda_verb alc882_sixstack_ch8_init[] = {
6161 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6162 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6163 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6164 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6168 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6169 { 6, alc882_sixstack_ch6_init },
6170 { 8, alc882_sixstack_ch8_init },
6174 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6180 static struct hda_verb alc885_mbp_ch2_init[] = {
6181 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6182 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6183 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6190 static struct hda_verb alc885_mbp_ch6_init[] = {
6191 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6192 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6193 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6194 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6195 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6199 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6200 { 2, alc885_mbp_ch2_init },
6201 { 6, alc885_mbp_ch6_init },
6205 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6206 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6208 static struct snd_kcontrol_new alc882_base_mixer[] = {
6209 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6210 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6211 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6212 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6213 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6214 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6215 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6216 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6217 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6218 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6219 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6220 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6221 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6222 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6223 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6224 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6225 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6226 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6227 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6228 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6229 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6233 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6234 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6235 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6236 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6237 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6238 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6239 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6240 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6241 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
6242 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
6243 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6246 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6247 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6248 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6249 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6250 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6251 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6252 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6254 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6255 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6259 static struct snd_kcontrol_new alc882_targa_mixer[] = {
6260 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6261 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6262 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6263 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6264 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6265 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6266 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6267 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6268 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6269 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6270 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6271 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6272 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6276 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6277 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6279 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6280 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6281 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6282 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6283 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6284 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6285 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6286 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6287 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6288 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6289 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6290 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6291 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6292 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6296 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6297 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6298 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6299 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6300 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6301 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6302 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6303 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6305 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6310 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6312 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6313 .name = "Channel Mode",
6314 .info = alc_ch_mode_info,
6315 .get = alc_ch_mode_get,
6316 .put = alc_ch_mode_put,
6321 static struct hda_verb alc882_init_verbs[] = {
6322 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6323 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6324 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6327 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6328 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6329 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6331 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6332 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6333 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6335 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6336 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6337 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6339 /* Front Pin: output 0 (0x0c) */
6340 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6341 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6342 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6343 /* Rear Pin: output 1 (0x0d) */
6344 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6345 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6346 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6347 /* CLFE Pin: output 2 (0x0e) */
6348 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6349 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6350 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6351 /* Side Pin: output 3 (0x0f) */
6352 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6353 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6354 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6355 /* Mic (rear) pin: input vref at 80% */
6356 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6357 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6358 /* Front Mic pin: input vref at 80% */
6359 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6360 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6361 /* Line In pin: input */
6362 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6363 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6364 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6365 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6366 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6367 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6368 /* CD pin widget for input */
6369 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6371 /* FIXME: use matrix-type input source selection */
6372 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6373 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6374 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6375 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6377 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6379 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6381 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6382 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6384 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6385 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6386 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6387 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6388 /* ADC1: mute amp left and right */
6389 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6390 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6391 /* ADC2: mute amp left and right */
6392 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6393 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6394 /* ADC3: mute amp left and right */
6395 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6396 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6401 static struct hda_verb alc882_eapd_verbs[] = {
6402 /* change to EAPD mode */
6403 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6404 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6409 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6410 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6411 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6412 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6413 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6414 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6415 /* FIXME: this looks suspicious...
6416 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6417 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6422 static struct hda_verb alc882_macpro_init_verbs[] = {
6423 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6424 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6425 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6427 /* Front Pin: output 0 (0x0c) */
6428 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6429 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6430 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6431 /* Front Mic pin: input vref at 80% */
6432 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6433 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6434 /* Speaker: output */
6435 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6436 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6437 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6438 /* Headphone output (output 0 - 0x0c) */
6439 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6440 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6441 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6443 /* FIXME: use matrix-type input source selection */
6444 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6445 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6451 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6452 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6453 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6454 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6456 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6457 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6458 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6459 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6460 /* ADC1: mute amp left and right */
6461 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6462 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6463 /* ADC2: mute amp left and right */
6464 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6465 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6466 /* ADC3: mute amp left and right */
6467 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6468 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6473 /* Macbook Pro rev3 */
6474 static struct hda_verb alc885_mbp3_init_verbs[] = {
6475 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6476 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6477 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6478 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6480 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6481 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6482 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6483 /* Front Pin: output 0 (0x0c) */
6484 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6485 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6486 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6487 /* HP Pin: output 0 (0x0d) */
6488 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6489 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6490 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6491 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6492 /* Mic (rear) pin: input vref at 80% */
6493 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6494 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6495 /* Front Mic pin: input vref at 80% */
6496 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6497 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6498 /* Line In pin: use output 1 when in LineOut mode */
6499 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6500 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6501 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6503 /* FIXME: use matrix-type input source selection */
6504 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6505 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6506 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6507 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6508 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6509 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6511 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6512 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6513 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6514 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6516 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6517 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6518 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6519 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6520 /* ADC1: mute amp left and right */
6521 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6522 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6523 /* ADC2: mute amp left and right */
6524 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6525 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6526 /* ADC3: mute amp left and right */
6527 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6528 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6533 /* iMac 24 mixer. */
6534 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6535 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6536 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6540 /* iMac 24 init verbs. */
6541 static struct hda_verb alc885_imac24_init_verbs[] = {
6542 /* Internal speakers: output 0 (0x0c) */
6543 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6544 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6545 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6546 /* Internal speakers: output 0 (0x0c) */
6547 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6548 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6549 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6550 /* Headphone: output 0 (0x0c) */
6551 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6552 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6553 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6554 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6555 /* Front Mic: input vref at 80% */
6556 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6557 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6561 /* Toggle speaker-output according to the hp-jack state */
6562 static void alc885_imac24_automute(struct hda_codec *codec)
6564 unsigned int present;
6566 present = snd_hda_codec_read(codec, 0x14, 0,
6567 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6568 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6569 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6570 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6571 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6574 /* Processes unsolicited events. */
6575 static void alc885_imac24_unsol_event(struct hda_codec *codec,
6578 /* Headphone insertion or removal. */
6579 if ((res >> 26) == ALC880_HP_EVENT)
6580 alc885_imac24_automute(codec);
6583 static void alc885_mbp3_automute(struct hda_codec *codec)
6585 unsigned int present;
6587 present = snd_hda_codec_read(codec, 0x15, 0,
6588 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6589 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6590 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6591 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6592 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6595 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6598 /* Headphone insertion or removal. */
6599 if ((res >> 26) == ALC880_HP_EVENT)
6600 alc885_mbp3_automute(codec);
6604 static struct hda_verb alc882_targa_verbs[] = {
6605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6606 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6608 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6609 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6611 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6612 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6613 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6615 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6616 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6617 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6618 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6622 /* toggle speaker-output according to the hp-jack state */
6623 static void alc882_targa_automute(struct hda_codec *codec)
6625 unsigned int present;
6627 present = snd_hda_codec_read(codec, 0x14, 0,
6628 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6629 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6630 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6631 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6635 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6637 /* Looks like the unsol event is incompatible with the standard
6638 * definition. 4bit tag is placed at 26 bit!
6640 if (((res >> 26) == ALC880_HP_EVENT)) {
6641 alc882_targa_automute(codec);
6645 static struct hda_verb alc882_asus_a7j_verbs[] = {
6646 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6647 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6649 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6650 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6651 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6653 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6655 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6657 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6658 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6659 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6663 static struct hda_verb alc882_asus_a7m_verbs[] = {
6664 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6665 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6667 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6668 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6669 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6671 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6672 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6673 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6675 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6676 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6677 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6681 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6683 unsigned int gpiostate, gpiomask, gpiodir;
6685 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6686 AC_VERB_GET_GPIO_DATA, 0);
6689 gpiostate |= (1 << pin);
6691 gpiostate &= ~(1 << pin);
6693 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6694 AC_VERB_GET_GPIO_MASK, 0);
6695 gpiomask |= (1 << pin);
6697 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6698 AC_VERB_GET_GPIO_DIRECTION, 0);
6699 gpiodir |= (1 << pin);
6702 snd_hda_codec_write(codec, codec->afg, 0,
6703 AC_VERB_SET_GPIO_MASK, gpiomask);
6704 snd_hda_codec_write(codec, codec->afg, 0,
6705 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6709 snd_hda_codec_write(codec, codec->afg, 0,
6710 AC_VERB_SET_GPIO_DATA, gpiostate);
6713 /* set up GPIO at initialization */
6714 static void alc885_macpro_init_hook(struct hda_codec *codec)
6716 alc882_gpio_mute(codec, 0, 0);
6717 alc882_gpio_mute(codec, 1, 0);
6720 /* set up GPIO and update auto-muting at initialization */
6721 static void alc885_imac24_init_hook(struct hda_codec *codec)
6723 alc885_macpro_init_hook(codec);
6724 alc885_imac24_automute(codec);
6728 * generic initialization of ADC, input mixers and output mixers
6730 static struct hda_verb alc882_auto_init_verbs[] = {
6732 * Unmute ADC0-2 and set the default input to mic-in
6734 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6735 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6736 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6737 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6738 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6739 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6741 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6743 * Note: PASD motherboards uses the Line In 2 as the input for
6744 * front panel mic (mic 2)
6746 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6747 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6748 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6749 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6750 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6751 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6754 * Set up output mixers (0x0c - 0x0f)
6756 /* set vol=0 to output mixers */
6757 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6758 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6759 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6760 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6761 /* set up input amps for analog loopback */
6762 /* Amp Indices: DAC = 0, mixer = 1 */
6763 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6764 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6765 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6766 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6767 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6768 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6769 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6770 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6771 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6772 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6774 /* FIXME: use matrix-type input source selection */
6775 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6776 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6777 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6778 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6779 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6780 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6782 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6783 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6784 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6785 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6787 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6788 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6790 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6795 #ifdef CONFIG_SND_HDA_POWER_SAVE
6796 #define alc882_loopbacks alc880_loopbacks
6799 /* pcm configuration: identiacal with ALC880 */
6800 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6801 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6802 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6803 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6806 * configuration and preset
6808 static const char *alc882_models[ALC882_MODEL_LAST] = {
6809 [ALC882_3ST_DIG] = "3stack-dig",
6810 [ALC882_6ST_DIG] = "6stack-dig",
6811 [ALC882_ARIMA] = "arima",
6812 [ALC882_W2JC] = "w2jc",
6813 [ALC882_TARGA] = "targa",
6814 [ALC882_ASUS_A7J] = "asus-a7j",
6815 [ALC882_ASUS_A7M] = "asus-a7m",
6816 [ALC885_MACPRO] = "macpro",
6817 [ALC885_MBP3] = "mbp3",
6818 [ALC885_IMAC24] = "imac24",
6819 [ALC882_AUTO] = "auto",
6822 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6823 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6824 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6825 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6826 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6827 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6828 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6829 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6830 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6831 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6832 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6833 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6834 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6838 static struct alc_config_preset alc882_presets[] = {
6839 [ALC882_3ST_DIG] = {
6840 .mixers = { alc882_base_mixer },
6841 .init_verbs = { alc882_init_verbs },
6842 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6843 .dac_nids = alc882_dac_nids,
6844 .dig_out_nid = ALC882_DIGOUT_NID,
6845 .dig_in_nid = ALC882_DIGIN_NID,
6846 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6847 .channel_mode = alc882_ch_modes,
6849 .input_mux = &alc882_capture_source,
6851 [ALC882_6ST_DIG] = {
6852 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6853 .init_verbs = { alc882_init_verbs },
6854 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6855 .dac_nids = alc882_dac_nids,
6856 .dig_out_nid = ALC882_DIGOUT_NID,
6857 .dig_in_nid = ALC882_DIGIN_NID,
6858 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6859 .channel_mode = alc882_sixstack_modes,
6860 .input_mux = &alc882_capture_source,
6863 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6864 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6865 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6866 .dac_nids = alc882_dac_nids,
6867 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6868 .channel_mode = alc882_sixstack_modes,
6869 .input_mux = &alc882_capture_source,
6872 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6873 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6874 alc880_gpio1_init_verbs },
6875 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6876 .dac_nids = alc882_dac_nids,
6877 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6878 .channel_mode = alc880_threestack_modes,
6880 .input_mux = &alc882_capture_source,
6881 .dig_out_nid = ALC882_DIGOUT_NID,
6884 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6885 .init_verbs = { alc885_mbp3_init_verbs,
6886 alc880_gpio1_init_verbs },
6887 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6888 .dac_nids = alc882_dac_nids,
6889 .channel_mode = alc885_mbp_6ch_modes,
6890 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6891 .input_mux = &alc882_capture_source,
6892 .dig_out_nid = ALC882_DIGOUT_NID,
6893 .dig_in_nid = ALC882_DIGIN_NID,
6894 .unsol_event = alc885_mbp3_unsol_event,
6895 .init_hook = alc885_mbp3_automute,
6898 .mixers = { alc882_macpro_mixer },
6899 .init_verbs = { alc882_macpro_init_verbs },
6900 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6901 .dac_nids = alc882_dac_nids,
6902 .dig_out_nid = ALC882_DIGOUT_NID,
6903 .dig_in_nid = ALC882_DIGIN_NID,
6904 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6905 .channel_mode = alc882_ch_modes,
6906 .input_mux = &alc882_capture_source,
6907 .init_hook = alc885_macpro_init_hook,
6910 .mixers = { alc885_imac24_mixer },
6911 .init_verbs = { alc885_imac24_init_verbs },
6912 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6913 .dac_nids = alc882_dac_nids,
6914 .dig_out_nid = ALC882_DIGOUT_NID,
6915 .dig_in_nid = ALC882_DIGIN_NID,
6916 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6917 .channel_mode = alc882_ch_modes,
6918 .input_mux = &alc882_capture_source,
6919 .unsol_event = alc885_imac24_unsol_event,
6920 .init_hook = alc885_imac24_init_hook,
6923 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
6924 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6925 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6926 .dac_nids = alc882_dac_nids,
6927 .dig_out_nid = ALC882_DIGOUT_NID,
6928 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6929 .adc_nids = alc882_adc_nids,
6930 .capsrc_nids = alc882_capsrc_nids,
6931 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6932 .channel_mode = alc882_3ST_6ch_modes,
6934 .input_mux = &alc882_capture_source,
6935 .unsol_event = alc882_targa_unsol_event,
6936 .init_hook = alc882_targa_automute,
6938 [ALC882_ASUS_A7J] = {
6939 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
6940 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6941 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6942 .dac_nids = alc882_dac_nids,
6943 .dig_out_nid = ALC882_DIGOUT_NID,
6944 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6945 .adc_nids = alc882_adc_nids,
6946 .capsrc_nids = alc882_capsrc_nids,
6947 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6948 .channel_mode = alc882_3ST_6ch_modes,
6950 .input_mux = &alc882_capture_source,
6952 [ALC882_ASUS_A7M] = {
6953 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6954 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6955 alc880_gpio1_init_verbs,
6956 alc882_asus_a7m_verbs },
6957 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6958 .dac_nids = alc882_dac_nids,
6959 .dig_out_nid = ALC882_DIGOUT_NID,
6960 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6961 .channel_mode = alc880_threestack_modes,
6963 .input_mux = &alc882_capture_source,
6972 PINFIX_ABIT_AW9D_MAX
6975 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6976 { 0x15, 0x01080104 }, /* side */
6977 { 0x16, 0x01011012 }, /* rear */
6978 { 0x17, 0x01016011 }, /* clfe */
6982 static const struct alc_pincfg *alc882_pin_fixes[] = {
6983 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6986 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6987 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6992 * BIOS auto configuration
6994 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6995 hda_nid_t nid, int pin_type,
6999 struct alc_spec *spec = codec->spec;
7002 alc_set_pin_output(codec, nid, pin_type);
7003 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7006 idx = spec->multiout.dac_nids[dac_idx] - 2;
7007 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7011 static void alc882_auto_init_multi_out(struct hda_codec *codec)
7013 struct alc_spec *spec = codec->spec;
7016 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7017 for (i = 0; i <= HDA_SIDE; i++) {
7018 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7019 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7021 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
7026 static void alc882_auto_init_hp_out(struct hda_codec *codec)
7028 struct alc_spec *spec = codec->spec;
7031 pin = spec->autocfg.hp_pins[0];
7032 if (pin) /* connect to front */
7034 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7035 pin = spec->autocfg.speaker_pins[0];
7037 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
7040 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7041 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7043 static void alc882_auto_init_analog_input(struct hda_codec *codec)
7045 struct alc_spec *spec = codec->spec;
7048 for (i = 0; i < AUTO_PIN_LAST; i++) {
7049 hda_nid_t nid = spec->autocfg.input_pins[i];
7052 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7053 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7054 snd_hda_codec_write(codec, nid, 0,
7055 AC_VERB_SET_AMP_GAIN_MUTE,
7060 static void alc882_auto_init_input_src(struct hda_codec *codec)
7062 struct alc_spec *spec = codec->spec;
7065 for (c = 0; c < spec->num_adc_nids; c++) {
7066 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7067 hda_nid_t nid = spec->capsrc_nids[c];
7068 unsigned int mux_idx;
7069 const struct hda_input_mux *imux;
7070 int conns, mute, idx, item;
7072 conns = snd_hda_get_connections(codec, nid, conn_list,
7073 ARRAY_SIZE(conn_list));
7076 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7077 imux = &spec->input_mux[mux_idx];
7078 for (idx = 0; idx < conns; idx++) {
7079 /* if the current connection is the selected one,
7080 * unmute it as default - otherwise mute it
7082 mute = AMP_IN_MUTE(idx);
7083 for (item = 0; item < imux->num_items; item++) {
7084 if (imux->items[item].index == idx) {
7085 if (spec->cur_mux[c] == item)
7086 mute = AMP_IN_UNMUTE(idx);
7090 /* check if we have a selector or mixer
7091 * we could check for the widget type instead, but
7092 * just check for Amp-In presence (in case of mixer
7093 * without amp-in there is something wrong, this
7094 * function shouldn't be used or capsrc nid is wrong)
7096 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7097 snd_hda_codec_write(codec, nid, 0,
7098 AC_VERB_SET_AMP_GAIN_MUTE,
7100 else if (mute != AMP_IN_MUTE(idx))
7101 snd_hda_codec_write(codec, nid, 0,
7102 AC_VERB_SET_CONNECT_SEL,
7108 /* add mic boosts if needed */
7109 static int alc_auto_add_mic_boost(struct hda_codec *codec)
7111 struct alc_spec *spec = codec->spec;
7115 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
7116 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7117 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7119 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7123 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
7124 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7125 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7127 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7134 /* almost identical with ALC880 parser... */
7135 static int alc882_parse_auto_config(struct hda_codec *codec)
7137 struct alc_spec *spec = codec->spec;
7138 int err = alc880_parse_auto_config(codec);
7143 return 0; /* no config found */
7145 err = alc_auto_add_mic_boost(codec);
7149 /* hack - override the init verbs */
7150 spec->init_verbs[0] = alc882_auto_init_verbs;
7152 return 1; /* config found */
7155 /* additional initialization for auto-configuration model */
7156 static void alc882_auto_init(struct hda_codec *codec)
7158 struct alc_spec *spec = codec->spec;
7159 alc882_auto_init_multi_out(codec);
7160 alc882_auto_init_hp_out(codec);
7161 alc882_auto_init_analog_input(codec);
7162 alc882_auto_init_input_src(codec);
7163 if (spec->unsol_event)
7164 alc_inithook(codec);
7167 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7169 static int patch_alc882(struct hda_codec *codec)
7171 struct alc_spec *spec;
7172 int err, board_config;
7174 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7180 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7184 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7185 /* Pick up systems that don't supply PCI SSID */
7186 switch (codec->subsystem_id) {
7187 case 0x106b0c00: /* Mac Pro */
7188 board_config = ALC885_MACPRO;
7190 case 0x106b1000: /* iMac 24 */
7191 case 0x106b2800: /* AppleTV */
7192 case 0x106b3e00: /* iMac 24 Aluminium */
7193 board_config = ALC885_IMAC24;
7195 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
7196 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7197 case 0x106b00a4: /* MacbookPro4,1 */
7198 case 0x106b2c00: /* Macbook Pro rev3 */
7199 case 0x106b3600: /* Macbook 3.1 */
7200 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7201 board_config = ALC885_MBP3;
7204 /* ALC889A is handled better as ALC888-compatible */
7205 if (codec->revision_id == 0x100101 ||
7206 codec->revision_id == 0x100103) {
7208 return patch_alc883(codec);
7210 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
7211 "trying auto-probe from BIOS...\n");
7212 board_config = ALC882_AUTO;
7216 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7218 if (board_config == ALC882_AUTO) {
7219 /* automatic parse from the BIOS config */
7220 err = alc882_parse_auto_config(codec);
7226 "hda_codec: Cannot set up configuration "
7227 "from BIOS. Using base mode...\n");
7228 board_config = ALC882_3ST_DIG;
7232 err = snd_hda_attach_beep_device(codec, 0x1);
7238 if (board_config != ALC882_AUTO)
7239 setup_preset(spec, &alc882_presets[board_config]);
7241 if (codec->vendor_id == 0x10ec0885) {
7242 spec->stream_name_analog = "ALC885 Analog";
7243 spec->stream_name_digital = "ALC885 Digital";
7245 spec->stream_name_analog = "ALC882 Analog";
7246 spec->stream_name_digital = "ALC882 Digital";
7249 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7250 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7251 /* FIXME: setup DAC5 */
7252 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7253 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7255 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7256 spec->stream_digital_capture = &alc882_pcm_digital_capture;
7258 spec->capture_style = CAPT_MIX; /* matrix-style capture */
7259 if (!spec->adc_nids && spec->input_mux) {
7260 /* check whether NID 0x07 is valid */
7261 unsigned int wcap = get_wcaps(codec, 0x07);
7263 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7264 if (wcap != AC_WID_AUD_IN) {
7265 spec->adc_nids = alc882_adc_nids_alt;
7266 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7267 spec->capsrc_nids = alc882_capsrc_nids_alt;
7269 spec->adc_nids = alc882_adc_nids;
7270 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7271 spec->capsrc_nids = alc882_capsrc_nids;
7274 set_capture_mixer(spec);
7275 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7277 spec->vmaster_nid = 0x0c;
7279 codec->patch_ops = alc_patch_ops;
7280 if (board_config == ALC882_AUTO)
7281 spec->init_hook = alc882_auto_init;
7282 #ifdef CONFIG_SND_HDA_POWER_SAVE
7283 if (!spec->loopback.amplist)
7284 spec->loopback.amplist = alc882_loopbacks;
7286 codec->proc_widget_hook = print_realtek_coef;
7294 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7295 * configuration. Each pin widget can choose any input DACs and a mixer.
7296 * Each ADC is connected from a mixer of all inputs. This makes possible
7297 * 6-channel independent captures.
7299 * In addition, an independent DAC for the multi-playback (not used in this
7302 #define ALC883_DIGOUT_NID 0x06
7303 #define ALC883_DIGIN_NID 0x0a
7305 #define ALC1200_DIGOUT_NID 0x10
7307 static hda_nid_t alc883_dac_nids[4] = {
7308 /* front, rear, clfe, rear_surr */
7309 0x02, 0x03, 0x04, 0x05
7312 static hda_nid_t alc883_adc_nids[2] = {
7317 static hda_nid_t alc883_adc_nids_alt[1] = {
7322 static hda_nid_t alc883_adc_nids_rev[2] = {
7327 #define alc889_adc_nids alc880_adc_nids
7329 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7331 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7333 #define alc889_capsrc_nids alc882_capsrc_nids
7336 /* FIXME: should be a matrix-type input source selection */
7338 static struct hda_input_mux alc883_capture_source = {
7342 { "Front Mic", 0x1 },
7348 static struct hda_input_mux alc883_3stack_6ch_intel = {
7352 { "Front Mic", 0x0 },
7358 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7366 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7376 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7384 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7388 { "Front Mic", 0x1 },
7393 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7404 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7411 static struct hda_verb alc883_3ST_ch2_init[] = {
7412 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7413 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7414 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7415 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7422 static struct hda_verb alc883_3ST_ch4_init[] = {
7423 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7424 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7425 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7426 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7427 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7434 static struct hda_verb alc883_3ST_ch6_init[] = {
7435 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7436 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7437 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7438 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7439 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7440 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7444 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7445 { 2, alc883_3ST_ch2_init },
7446 { 4, alc883_3ST_ch4_init },
7447 { 6, alc883_3ST_ch6_init },
7453 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7454 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7455 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7456 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7457 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7464 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7465 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7466 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7467 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7468 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7469 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7476 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7477 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7478 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7479 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7480 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7481 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7482 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7486 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7487 { 2, alc883_3ST_ch2_intel_init },
7488 { 4, alc883_3ST_ch4_intel_init },
7489 { 6, alc883_3ST_ch6_intel_init },
7495 static struct hda_verb alc883_sixstack_ch6_init[] = {
7496 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7497 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7498 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7499 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7506 static struct hda_verb alc883_sixstack_ch8_init[] = {
7507 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7508 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7509 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7510 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7514 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7515 { 6, alc883_sixstack_ch6_init },
7516 { 8, alc883_sixstack_ch8_init },
7519 static struct hda_verb alc883_medion_eapd_verbs[] = {
7520 /* eanable EAPD on medion laptop */
7521 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7522 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7526 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7527 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7530 static struct snd_kcontrol_new alc883_base_mixer[] = {
7531 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7532 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7533 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7534 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7535 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7536 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7537 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7538 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7539 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7540 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7541 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7542 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7543 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7544 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7545 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7546 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7547 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7548 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7549 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7550 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7551 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7555 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7556 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7557 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7558 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7559 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7560 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7561 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7562 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7563 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7564 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7565 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7566 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7567 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7568 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7572 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7573 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7574 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7575 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7576 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7577 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7578 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7579 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7580 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7581 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7582 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7586 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7587 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7588 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7589 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7590 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7591 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7592 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7593 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7594 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7595 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7596 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7600 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7601 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7602 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7603 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7604 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7605 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7606 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7607 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7608 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7609 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7610 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7611 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7612 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7613 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7617 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7618 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7619 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7620 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7621 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7622 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7623 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7624 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7625 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7626 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7627 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7628 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7629 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7630 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7631 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7632 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7633 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7634 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7635 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7636 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7640 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7641 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7642 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7643 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7644 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7645 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7647 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7648 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7649 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7651 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7652 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7653 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7654 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7655 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7656 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7657 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7658 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7659 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7660 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7664 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7665 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7666 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7667 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7668 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7669 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7670 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7671 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7672 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7673 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7674 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7675 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7676 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7677 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7678 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7679 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7680 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7681 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7682 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7683 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7687 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7688 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7689 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7690 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7691 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7692 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7693 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7694 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7695 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7696 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7697 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7698 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7699 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7700 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7701 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7702 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7703 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7707 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7708 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7709 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7710 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7711 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7712 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7713 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7714 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7715 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7716 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7717 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7718 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7722 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7723 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7724 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7725 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7726 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7727 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7728 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7729 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7730 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7734 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7735 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7736 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7737 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7738 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7739 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7740 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7741 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7742 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7743 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7747 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7748 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7749 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7750 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7751 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7752 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7753 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7754 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7755 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7756 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7760 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7761 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7762 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7763 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7764 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7765 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7766 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7767 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7768 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7772 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7773 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7774 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7775 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7776 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7777 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7778 0x0d, 1, 0x0, HDA_OUTPUT),
7779 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7780 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7781 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7782 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7783 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7784 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7785 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7786 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7787 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7788 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7789 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7790 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7791 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7792 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7793 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7794 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7795 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7799 static struct hda_bind_ctls alc883_bind_cap_vol = {
7800 .ops = &snd_hda_bind_vol,
7802 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7803 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7808 static struct hda_bind_ctls alc883_bind_cap_switch = {
7809 .ops = &snd_hda_bind_sw,
7811 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7812 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7817 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7818 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7819 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7820 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7821 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7822 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7823 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7824 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7825 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7829 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7830 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7831 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7834 /* .name = "Capture Source", */
7835 .name = "Input Source",
7837 .info = alc_mux_enum_info,
7838 .get = alc_mux_enum_get,
7839 .put = alc_mux_enum_put,
7844 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7846 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7847 .name = "Channel Mode",
7848 .info = alc_ch_mode_info,
7849 .get = alc_ch_mode_get,
7850 .put = alc_ch_mode_put,
7855 static struct hda_verb alc883_init_verbs[] = {
7856 /* ADC1: mute amp left and right */
7857 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7858 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7859 /* ADC2: mute amp left and right */
7860 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7861 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7862 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7863 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7864 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7865 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7867 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7868 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7869 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7871 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7872 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7873 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7875 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7876 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7877 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7879 /* mute analog input loopbacks */
7880 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7881 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7882 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7883 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7884 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7886 /* Front Pin: output 0 (0x0c) */
7887 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7888 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7889 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7890 /* Rear Pin: output 1 (0x0d) */
7891 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7892 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7893 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7894 /* CLFE Pin: output 2 (0x0e) */
7895 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7896 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7897 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7898 /* Side Pin: output 3 (0x0f) */
7899 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7900 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7901 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7902 /* Mic (rear) pin: input vref at 80% */
7903 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7904 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7905 /* Front Mic pin: input vref at 80% */
7906 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7907 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7908 /* Line In pin: input */
7909 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7910 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7911 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7912 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7913 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7914 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7915 /* CD pin widget for input */
7916 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7918 /* FIXME: use matrix-type input source selection */
7919 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7921 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7922 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7923 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7924 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7926 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7927 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7928 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7933 /* toggle speaker-output according to the hp-jack state */
7934 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7936 unsigned int present;
7938 present = snd_hda_codec_read(codec, 0x15, 0,
7939 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7940 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7941 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7942 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7943 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7946 /* auto-toggle front mic */
7948 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7950 unsigned int present;
7953 present = snd_hda_codec_read(codec, 0x18, 0,
7954 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7955 bits = present ? HDA_AMP_MUTE : 0;
7956 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7960 static void alc883_mitac_automute(struct hda_codec *codec)
7962 alc883_mitac_hp_automute(codec);
7963 /* alc883_mitac_mic_automute(codec); */
7966 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7969 switch (res >> 26) {
7970 case ALC880_HP_EVENT:
7971 alc883_mitac_hp_automute(codec);
7973 case ALC880_MIC_EVENT:
7974 /* alc883_mitac_mic_automute(codec); */
7979 static struct hda_verb alc883_mitac_verbs[] = {
7981 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7982 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7984 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7985 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7987 /* enable unsolicited event */
7988 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7989 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7994 static struct hda_verb alc883_clevo_m720_verbs[] = {
7996 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7997 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7999 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8000 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8002 /* enable unsolicited event */
8003 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8004 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8009 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8011 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8012 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8014 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8015 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8017 /* enable unsolicited event */
8018 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8023 static struct hda_verb alc883_tagra_verbs[] = {
8024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8027 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8028 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8030 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8031 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8032 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8034 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8035 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
8036 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
8037 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
8042 static struct hda_verb alc883_lenovo_101e_verbs[] = {
8043 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8044 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8045 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8049 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8050 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8051 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8052 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8053 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8057 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8058 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8059 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8060 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8061 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8062 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8066 static struct hda_verb alc883_haier_w66_verbs[] = {
8067 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8068 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8070 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8072 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8073 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8074 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8075 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8079 static struct hda_verb alc888_lenovo_sky_verbs[] = {
8080 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8081 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8082 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8083 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8084 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8085 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8086 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8087 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8091 static struct hda_verb alc888_6st_dell_verbs[] = {
8092 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8096 static void alc888_3st_hp_front_automute(struct hda_codec *codec)
8098 unsigned int present, bits;
8100 present = snd_hda_codec_read(codec, 0x1b, 0,
8101 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8102 bits = present ? HDA_AMP_MUTE : 0;
8103 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8104 HDA_AMP_MUTE, bits);
8105 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8106 HDA_AMP_MUTE, bits);
8107 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
8108 HDA_AMP_MUTE, bits);
8111 static void alc888_3st_hp_unsol_event(struct hda_codec *codec,
8114 switch (res >> 26) {
8115 case ALC880_HP_EVENT:
8116 alc888_3st_hp_front_automute(codec);
8121 static struct hda_verb alc888_3st_hp_verbs[] = {
8122 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8123 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8124 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8125 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8132 static struct hda_verb alc888_3st_hp_2ch_init[] = {
8133 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8134 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8135 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8136 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8143 static struct hda_verb alc888_3st_hp_4ch_init[] = {
8144 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8145 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8146 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8147 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8148 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8155 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8156 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8157 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8158 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8159 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8160 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8161 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8165 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8166 { 2, alc888_3st_hp_2ch_init },
8167 { 4, alc888_3st_hp_4ch_init },
8168 { 6, alc888_3st_hp_6ch_init },
8171 /* toggle front-jack and RCA according to the hp-jack state */
8172 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8174 unsigned int present;
8176 present = snd_hda_codec_read(codec, 0x1b, 0,
8177 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8178 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8179 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8180 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8181 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8184 /* toggle RCA according to the front-jack state */
8185 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8187 unsigned int present;
8189 present = snd_hda_codec_read(codec, 0x14, 0,
8190 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8191 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8192 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8195 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8198 if ((res >> 26) == ALC880_HP_EVENT)
8199 alc888_lenovo_ms7195_front_automute(codec);
8200 if ((res >> 26) == ALC880_FRONT_EVENT)
8201 alc888_lenovo_ms7195_rca_automute(codec);
8204 static struct hda_verb alc883_medion_md2_verbs[] = {
8205 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8206 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8208 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8210 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8214 /* toggle speaker-output according to the hp-jack state */
8215 static void alc883_medion_md2_automute(struct hda_codec *codec)
8217 unsigned int present;
8219 present = snd_hda_codec_read(codec, 0x14, 0,
8220 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8221 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8222 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8225 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
8228 if ((res >> 26) == ALC880_HP_EVENT)
8229 alc883_medion_md2_automute(codec);
8232 /* toggle speaker-output according to the hp-jack state */
8233 static void alc883_tagra_automute(struct hda_codec *codec)
8235 unsigned int present;
8238 present = snd_hda_codec_read(codec, 0x14, 0,
8239 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8240 bits = present ? HDA_AMP_MUTE : 0;
8241 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
8242 HDA_AMP_MUTE, bits);
8243 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8247 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
8249 if ((res >> 26) == ALC880_HP_EVENT)
8250 alc883_tagra_automute(codec);
8253 /* toggle speaker-output according to the hp-jack state */
8254 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
8256 unsigned int present;
8259 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
8260 & AC_PINSENSE_PRESENCE;
8261 bits = present ? HDA_AMP_MUTE : 0;
8262 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8263 HDA_AMP_MUTE, bits);
8266 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8268 unsigned int present;
8270 present = snd_hda_codec_read(codec, 0x18, 0,
8271 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8272 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8273 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8276 static void alc883_clevo_m720_automute(struct hda_codec *codec)
8278 alc883_clevo_m720_hp_automute(codec);
8279 alc883_clevo_m720_mic_automute(codec);
8282 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8285 switch (res >> 26) {
8286 case ALC880_HP_EVENT:
8287 alc883_clevo_m720_hp_automute(codec);
8289 case ALC880_MIC_EVENT:
8290 alc883_clevo_m720_mic_automute(codec);
8295 /* toggle speaker-output according to the hp-jack state */
8296 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
8298 unsigned int present;
8301 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8302 & AC_PINSENSE_PRESENCE;
8303 bits = present ? HDA_AMP_MUTE : 0;
8304 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8305 HDA_AMP_MUTE, bits);
8308 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
8311 if ((res >> 26) == ALC880_HP_EVENT)
8312 alc883_2ch_fujitsu_pi2515_automute(codec);
8315 static void alc883_haier_w66_automute(struct hda_codec *codec)
8317 unsigned int present;
8320 present = snd_hda_codec_read(codec, 0x1b, 0,
8321 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8322 bits = present ? 0x80 : 0;
8323 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8327 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
8330 if ((res >> 26) == ALC880_HP_EVENT)
8331 alc883_haier_w66_automute(codec);
8334 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8336 unsigned int present;
8339 present = snd_hda_codec_read(codec, 0x14, 0,
8340 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8341 bits = present ? HDA_AMP_MUTE : 0;
8342 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8343 HDA_AMP_MUTE, bits);
8346 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8348 unsigned int present;
8351 present = snd_hda_codec_read(codec, 0x1b, 0,
8352 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8353 bits = present ? HDA_AMP_MUTE : 0;
8354 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8355 HDA_AMP_MUTE, bits);
8356 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8357 HDA_AMP_MUTE, bits);
8360 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8363 if ((res >> 26) == ALC880_HP_EVENT)
8364 alc883_lenovo_101e_all_automute(codec);
8365 if ((res >> 26) == ALC880_FRONT_EVENT)
8366 alc883_lenovo_101e_ispeaker_automute(codec);
8369 /* toggle speaker-output according to the hp-jack state */
8370 static void alc883_acer_aspire_automute(struct hda_codec *codec)
8372 unsigned int present;
8374 present = snd_hda_codec_read(codec, 0x14, 0,
8375 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8376 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8377 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8378 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8379 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8382 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
8385 if ((res >> 26) == ALC880_HP_EVENT)
8386 alc883_acer_aspire_automute(codec);
8389 static struct hda_verb alc883_acer_eapd_verbs[] = {
8390 /* HP Pin: output 0 (0x0c) */
8391 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8392 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8393 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8394 /* Front Pin: output 0 (0x0c) */
8395 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8396 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8397 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8398 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8399 /* eanable EAPD on medion laptop */
8400 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8401 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8402 /* enable unsolicited event */
8403 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8407 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8409 unsigned int present;
8411 present = snd_hda_codec_read(codec, 0x1b, 0,
8412 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8413 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8414 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8415 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8416 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8417 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8418 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8419 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8420 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8423 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8426 switch (res >> 26) {
8427 case ALC880_HP_EVENT:
8428 /* printk(KERN_DEBUG "hp_event\n"); */
8429 alc888_6st_dell_front_automute(codec);
8434 static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8437 unsigned int present;
8439 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8440 present = snd_hda_codec_read(codec, 0x1b, 0,
8441 AC_VERB_GET_PIN_SENSE, 0);
8442 present = (present & 0x80000000) != 0;
8444 /* mute internal speaker */
8445 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8446 HDA_AMP_MUTE, HDA_AMP_MUTE);
8447 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8448 HDA_AMP_MUTE, HDA_AMP_MUTE);
8449 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8450 HDA_AMP_MUTE, HDA_AMP_MUTE);
8451 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8452 HDA_AMP_MUTE, HDA_AMP_MUTE);
8453 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8454 HDA_AMP_MUTE, HDA_AMP_MUTE);
8456 /* unmute internal speaker if necessary */
8457 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8458 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8459 HDA_AMP_MUTE, mute);
8460 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8461 HDA_AMP_MUTE, mute);
8462 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8463 HDA_AMP_MUTE, mute);
8464 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8465 HDA_AMP_MUTE, mute);
8466 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8467 HDA_AMP_MUTE, mute);
8471 static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8474 if ((res >> 26) == ALC880_HP_EVENT)
8475 alc888_lenovo_sky_front_automute(codec);
8479 * generic initialization of ADC, input mixers and output mixers
8481 static struct hda_verb alc883_auto_init_verbs[] = {
8483 * Unmute ADC0-2 and set the default input to mic-in
8485 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8486 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8487 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8490 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8492 * Note: PASD motherboards uses the Line In 2 as the input for
8493 * front panel mic (mic 2)
8495 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8496 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8497 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8498 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8499 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8500 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8503 * Set up output mixers (0x0c - 0x0f)
8505 /* set vol=0 to output mixers */
8506 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8507 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8508 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8509 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8510 /* set up input amps for analog loopback */
8511 /* Amp Indices: DAC = 0, mixer = 1 */
8512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8513 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8515 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8517 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8518 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8519 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8520 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8521 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8523 /* FIXME: use matrix-type input source selection */
8524 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8528 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8529 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8535 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8541 static struct hda_verb alc888_asus_m90v_verbs[] = {
8542 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8543 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8544 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8545 /* enable unsolicited event */
8546 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8547 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8551 static void alc883_nb_mic_automute(struct hda_codec *codec)
8553 unsigned int present;
8555 present = snd_hda_codec_read(codec, 0x18, 0,
8556 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8557 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8558 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8559 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8560 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8563 static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8565 unsigned int present;
8568 present = snd_hda_codec_read(codec, 0x1b, 0,
8569 AC_VERB_GET_PIN_SENSE, 0)
8570 & AC_PINSENSE_PRESENCE;
8571 bits = present ? 0 : PIN_OUT;
8572 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8574 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8576 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8580 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8583 switch (res >> 26) {
8584 case ALC880_HP_EVENT:
8585 alc883_M90V_speaker_automute(codec);
8587 case ALC880_MIC_EVENT:
8588 alc883_nb_mic_automute(codec);
8593 static void alc883_mode2_inithook(struct hda_codec *codec)
8595 alc883_M90V_speaker_automute(codec);
8596 alc883_nb_mic_automute(codec);
8599 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8600 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8601 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8602 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8603 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8604 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8605 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8606 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8607 /* enable unsolicited event */
8608 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8612 static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8614 unsigned int present;
8617 present = snd_hda_codec_read(codec, 0x14, 0,
8618 AC_VERB_GET_PIN_SENSE, 0)
8619 & AC_PINSENSE_PRESENCE;
8620 bits = present ? 0 : PIN_OUT;
8621 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8625 static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8628 switch (res >> 26) {
8629 case ALC880_HP_EVENT:
8630 alc883_eee1601_speaker_automute(codec);
8635 static void alc883_eee1601_inithook(struct hda_codec *codec)
8637 alc883_eee1601_speaker_automute(codec);
8640 #ifdef CONFIG_SND_HDA_POWER_SAVE
8641 #define alc883_loopbacks alc880_loopbacks
8644 /* pcm configuration: identiacal with ALC880 */
8645 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8646 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8647 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8648 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8649 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8652 * configuration and preset
8654 static const char *alc883_models[ALC883_MODEL_LAST] = {
8655 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8656 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8657 [ALC883_3ST_6ch] = "3stack-6ch",
8658 [ALC883_6ST_DIG] = "6stack-dig",
8659 [ALC883_TARGA_DIG] = "targa-dig",
8660 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8661 [ALC883_ACER] = "acer",
8662 [ALC883_ACER_ASPIRE] = "acer-aspire",
8663 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8664 [ALC883_MEDION] = "medion",
8665 [ALC883_MEDION_MD2] = "medion-md2",
8666 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8667 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8668 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8669 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8670 [ALC888_LENOVO_SKY] = "lenovo-sky",
8671 [ALC883_HAIER_W66] = "haier-w66",
8672 [ALC888_3ST_HP] = "3stack-hp",
8673 [ALC888_6ST_DELL] = "6stack-dell",
8674 [ALC883_MITAC] = "mitac",
8675 [ALC883_CLEVO_M720] = "clevo-m720",
8676 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8677 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8678 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8679 [ALC1200_ASUS_P5Q] = "asus-p5q",
8680 [ALC883_AUTO] = "auto",
8683 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8684 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8685 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8686 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8687 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8688 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8689 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8690 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8691 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8692 ALC888_ACER_ASPIRE_4930G),
8693 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8694 ALC888_ACER_ASPIRE_4930G),
8695 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
8696 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
8697 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8698 ALC888_ACER_ASPIRE_4930G),
8699 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8700 ALC888_ACER_ASPIRE_4930G),
8702 SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER),
8703 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8704 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8705 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8706 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8707 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8708 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8709 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8710 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8711 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8712 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8713 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8714 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8715 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8716 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8717 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8718 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8719 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8720 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8721 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8722 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8723 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8724 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8725 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8726 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8727 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8728 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8729 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8730 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8731 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8732 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8733 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8734 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8735 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8736 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8737 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8738 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8739 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8740 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8741 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8742 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8743 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8744 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8745 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8746 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8747 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8748 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8749 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8750 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8751 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8752 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8753 ALC883_FUJITSU_PI2515),
8754 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8755 ALC888_FUJITSU_XA3530),
8756 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8757 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8758 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8759 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8760 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8761 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8762 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8763 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8764 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8765 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8766 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8767 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8768 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8769 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8773 static hda_nid_t alc883_slave_dig_outs[] = {
8774 ALC1200_DIGOUT_NID, 0,
8777 static hda_nid_t alc1200_slave_dig_outs[] = {
8778 ALC883_DIGOUT_NID, 0,
8781 static struct alc_config_preset alc883_presets[] = {
8782 [ALC883_3ST_2ch_DIG] = {
8783 .mixers = { alc883_3ST_2ch_mixer },
8784 .init_verbs = { alc883_init_verbs },
8785 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8786 .dac_nids = alc883_dac_nids,
8787 .dig_out_nid = ALC883_DIGOUT_NID,
8788 .dig_in_nid = ALC883_DIGIN_NID,
8789 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8790 .channel_mode = alc883_3ST_2ch_modes,
8791 .input_mux = &alc883_capture_source,
8793 [ALC883_3ST_6ch_DIG] = {
8794 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8795 .init_verbs = { alc883_init_verbs },
8796 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8797 .dac_nids = alc883_dac_nids,
8798 .dig_out_nid = ALC883_DIGOUT_NID,
8799 .dig_in_nid = ALC883_DIGIN_NID,
8800 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8801 .channel_mode = alc883_3ST_6ch_modes,
8803 .input_mux = &alc883_capture_source,
8805 [ALC883_3ST_6ch] = {
8806 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8807 .init_verbs = { alc883_init_verbs },
8808 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8809 .dac_nids = alc883_dac_nids,
8810 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8811 .channel_mode = alc883_3ST_6ch_modes,
8813 .input_mux = &alc883_capture_source,
8815 [ALC883_3ST_6ch_INTEL] = {
8816 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8817 .init_verbs = { alc883_init_verbs },
8818 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8819 .dac_nids = alc883_dac_nids,
8820 .dig_out_nid = ALC883_DIGOUT_NID,
8821 .dig_in_nid = ALC883_DIGIN_NID,
8822 .slave_dig_outs = alc883_slave_dig_outs,
8823 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8824 .channel_mode = alc883_3ST_6ch_intel_modes,
8826 .input_mux = &alc883_3stack_6ch_intel,
8828 [ALC883_6ST_DIG] = {
8829 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8830 .init_verbs = { alc883_init_verbs },
8831 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8832 .dac_nids = alc883_dac_nids,
8833 .dig_out_nid = ALC883_DIGOUT_NID,
8834 .dig_in_nid = ALC883_DIGIN_NID,
8835 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8836 .channel_mode = alc883_sixstack_modes,
8837 .input_mux = &alc883_capture_source,
8839 [ALC883_TARGA_DIG] = {
8840 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8841 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8842 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8843 .dac_nids = alc883_dac_nids,
8844 .dig_out_nid = ALC883_DIGOUT_NID,
8845 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8846 .channel_mode = alc883_3ST_6ch_modes,
8848 .input_mux = &alc883_capture_source,
8849 .unsol_event = alc883_tagra_unsol_event,
8850 .init_hook = alc883_tagra_automute,
8852 [ALC883_TARGA_2ch_DIG] = {
8853 .mixers = { alc883_tagra_2ch_mixer},
8854 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8855 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8856 .dac_nids = alc883_dac_nids,
8857 .adc_nids = alc883_adc_nids_alt,
8858 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8859 .dig_out_nid = ALC883_DIGOUT_NID,
8860 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8861 .channel_mode = alc883_3ST_2ch_modes,
8862 .input_mux = &alc883_capture_source,
8863 .unsol_event = alc883_tagra_unsol_event,
8864 .init_hook = alc883_tagra_automute,
8867 .mixers = { alc883_base_mixer },
8868 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8869 * and the headphone jack. Turn this on and rely on the
8870 * standard mute methods whenever the user wants to turn
8871 * these outputs off.
8873 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8874 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8875 .dac_nids = alc883_dac_nids,
8876 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8877 .channel_mode = alc883_3ST_2ch_modes,
8878 .input_mux = &alc883_capture_source,
8880 [ALC883_ACER_ASPIRE] = {
8881 .mixers = { alc883_acer_aspire_mixer },
8882 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8883 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8884 .dac_nids = alc883_dac_nids,
8885 .dig_out_nid = ALC883_DIGOUT_NID,
8886 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8887 .channel_mode = alc883_3ST_2ch_modes,
8888 .input_mux = &alc883_capture_source,
8889 .unsol_event = alc883_acer_aspire_unsol_event,
8890 .init_hook = alc883_acer_aspire_automute,
8892 [ALC888_ACER_ASPIRE_4930G] = {
8893 .mixers = { alc888_base_mixer,
8894 alc883_chmode_mixer },
8895 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8896 alc888_acer_aspire_4930g_verbs },
8897 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8898 .dac_nids = alc883_dac_nids,
8899 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8900 .adc_nids = alc883_adc_nids_rev,
8901 .capsrc_nids = alc883_capsrc_nids_rev,
8902 .dig_out_nid = ALC883_DIGOUT_NID,
8903 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8904 .channel_mode = alc883_3ST_6ch_modes,
8907 ARRAY_SIZE(alc888_2_capture_sources),
8908 .input_mux = alc888_2_capture_sources,
8909 .unsol_event = alc888_acer_aspire_4930g_unsol_event,
8910 .init_hook = alc888_acer_aspire_4930g_automute,
8913 .mixers = { alc883_fivestack_mixer,
8914 alc883_chmode_mixer },
8915 .init_verbs = { alc883_init_verbs,
8916 alc883_medion_eapd_verbs },
8917 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8918 .dac_nids = alc883_dac_nids,
8919 .adc_nids = alc883_adc_nids_alt,
8920 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8921 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8922 .channel_mode = alc883_sixstack_modes,
8923 .input_mux = &alc883_capture_source,
8925 [ALC883_MEDION_MD2] = {
8926 .mixers = { alc883_medion_md2_mixer},
8927 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8928 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8929 .dac_nids = alc883_dac_nids,
8930 .dig_out_nid = ALC883_DIGOUT_NID,
8931 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8932 .channel_mode = alc883_3ST_2ch_modes,
8933 .input_mux = &alc883_capture_source,
8934 .unsol_event = alc883_medion_md2_unsol_event,
8935 .init_hook = alc883_medion_md2_automute,
8937 [ALC883_LAPTOP_EAPD] = {
8938 .mixers = { alc883_base_mixer },
8939 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8940 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8941 .dac_nids = alc883_dac_nids,
8942 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8943 .channel_mode = alc883_3ST_2ch_modes,
8944 .input_mux = &alc883_capture_source,
8946 [ALC883_CLEVO_M720] = {
8947 .mixers = { alc883_clevo_m720_mixer },
8948 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8949 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8950 .dac_nids = alc883_dac_nids,
8951 .dig_out_nid = ALC883_DIGOUT_NID,
8952 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8953 .channel_mode = alc883_3ST_2ch_modes,
8954 .input_mux = &alc883_capture_source,
8955 .unsol_event = alc883_clevo_m720_unsol_event,
8956 .init_hook = alc883_clevo_m720_automute,
8958 [ALC883_LENOVO_101E_2ch] = {
8959 .mixers = { alc883_lenovo_101e_2ch_mixer},
8960 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8961 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8962 .dac_nids = alc883_dac_nids,
8963 .adc_nids = alc883_adc_nids_alt,
8964 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8965 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8966 .channel_mode = alc883_3ST_2ch_modes,
8967 .input_mux = &alc883_lenovo_101e_capture_source,
8968 .unsol_event = alc883_lenovo_101e_unsol_event,
8969 .init_hook = alc883_lenovo_101e_all_automute,
8971 [ALC883_LENOVO_NB0763] = {
8972 .mixers = { alc883_lenovo_nb0763_mixer },
8973 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8974 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8975 .dac_nids = alc883_dac_nids,
8976 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8977 .channel_mode = alc883_3ST_2ch_modes,
8979 .input_mux = &alc883_lenovo_nb0763_capture_source,
8980 .unsol_event = alc883_medion_md2_unsol_event,
8981 .init_hook = alc883_medion_md2_automute,
8983 [ALC888_LENOVO_MS7195_DIG] = {
8984 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8985 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8986 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8987 .dac_nids = alc883_dac_nids,
8988 .dig_out_nid = ALC883_DIGOUT_NID,
8989 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8990 .channel_mode = alc883_3ST_6ch_modes,
8992 .input_mux = &alc883_capture_source,
8993 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8994 .init_hook = alc888_lenovo_ms7195_front_automute,
8996 [ALC883_HAIER_W66] = {
8997 .mixers = { alc883_tagra_2ch_mixer},
8998 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8999 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9000 .dac_nids = alc883_dac_nids,
9001 .dig_out_nid = ALC883_DIGOUT_NID,
9002 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9003 .channel_mode = alc883_3ST_2ch_modes,
9004 .input_mux = &alc883_capture_source,
9005 .unsol_event = alc883_haier_w66_unsol_event,
9006 .init_hook = alc883_haier_w66_automute,
9009 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9010 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
9011 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9012 .dac_nids = alc883_dac_nids,
9013 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9014 .channel_mode = alc888_3st_hp_modes,
9016 .input_mux = &alc883_capture_source,
9017 .unsol_event = alc888_3st_hp_unsol_event,
9018 .init_hook = alc888_3st_hp_front_automute,
9020 [ALC888_6ST_DELL] = {
9021 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9022 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9023 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9024 .dac_nids = alc883_dac_nids,
9025 .dig_out_nid = ALC883_DIGOUT_NID,
9026 .dig_in_nid = ALC883_DIGIN_NID,
9027 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9028 .channel_mode = alc883_sixstack_modes,
9029 .input_mux = &alc883_capture_source,
9030 .unsol_event = alc888_6st_dell_unsol_event,
9031 .init_hook = alc888_6st_dell_front_automute,
9034 .mixers = { alc883_mitac_mixer },
9035 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9036 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9037 .dac_nids = alc883_dac_nids,
9038 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9039 .channel_mode = alc883_3ST_2ch_modes,
9040 .input_mux = &alc883_capture_source,
9041 .unsol_event = alc883_mitac_unsol_event,
9042 .init_hook = alc883_mitac_automute,
9044 [ALC883_FUJITSU_PI2515] = {
9045 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9046 .init_verbs = { alc883_init_verbs,
9047 alc883_2ch_fujitsu_pi2515_verbs},
9048 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9049 .dac_nids = alc883_dac_nids,
9050 .dig_out_nid = ALC883_DIGOUT_NID,
9051 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9052 .channel_mode = alc883_3ST_2ch_modes,
9053 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9054 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
9055 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
9057 [ALC888_FUJITSU_XA3530] = {
9058 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9059 .init_verbs = { alc883_init_verbs,
9060 alc888_fujitsu_xa3530_verbs },
9061 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9062 .dac_nids = alc883_dac_nids,
9063 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9064 .adc_nids = alc883_adc_nids_rev,
9065 .capsrc_nids = alc883_capsrc_nids_rev,
9066 .dig_out_nid = ALC883_DIGOUT_NID,
9067 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9068 .channel_mode = alc888_4ST_8ch_intel_modes,
9070 ARRAY_SIZE(alc888_2_capture_sources),
9071 .input_mux = alc888_2_capture_sources,
9072 .unsol_event = alc888_fujitsu_xa3530_unsol_event,
9073 .init_hook = alc888_fujitsu_xa3530_automute,
9075 [ALC888_LENOVO_SKY] = {
9076 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9077 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9078 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9079 .dac_nids = alc883_dac_nids,
9080 .dig_out_nid = ALC883_DIGOUT_NID,
9081 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9082 .channel_mode = alc883_sixstack_modes,
9084 .input_mux = &alc883_lenovo_sky_capture_source,
9085 .unsol_event = alc883_lenovo_sky_unsol_event,
9086 .init_hook = alc888_lenovo_sky_front_automute,
9088 [ALC888_ASUS_M90V] = {
9089 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9090 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9091 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9092 .dac_nids = alc883_dac_nids,
9093 .dig_out_nid = ALC883_DIGOUT_NID,
9094 .dig_in_nid = ALC883_DIGIN_NID,
9095 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9096 .channel_mode = alc883_3ST_6ch_modes,
9098 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9099 .unsol_event = alc883_mode2_unsol_event,
9100 .init_hook = alc883_mode2_inithook,
9102 [ALC888_ASUS_EEE1601] = {
9103 .mixers = { alc883_asus_eee1601_mixer },
9104 .cap_mixer = alc883_asus_eee1601_cap_mixer,
9105 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9106 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9107 .dac_nids = alc883_dac_nids,
9108 .dig_out_nid = ALC883_DIGOUT_NID,
9109 .dig_in_nid = ALC883_DIGIN_NID,
9110 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9111 .channel_mode = alc883_3ST_2ch_modes,
9113 .input_mux = &alc883_asus_eee1601_capture_source,
9114 .unsol_event = alc883_eee1601_unsol_event,
9115 .init_hook = alc883_eee1601_inithook,
9117 [ALC1200_ASUS_P5Q] = {
9118 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9119 .init_verbs = { alc883_init_verbs },
9120 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9121 .dac_nids = alc883_dac_nids,
9122 .dig_out_nid = ALC1200_DIGOUT_NID,
9123 .dig_in_nid = ALC883_DIGIN_NID,
9124 .slave_dig_outs = alc1200_slave_dig_outs,
9125 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9126 .channel_mode = alc883_sixstack_modes,
9127 .input_mux = &alc883_capture_source,
9133 * BIOS auto configuration
9135 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9136 hda_nid_t nid, int pin_type,
9140 struct alc_spec *spec = codec->spec;
9143 alc_set_pin_output(codec, nid, pin_type);
9144 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9147 idx = spec->multiout.dac_nids[dac_idx] - 2;
9148 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9152 static void alc883_auto_init_multi_out(struct hda_codec *codec)
9154 struct alc_spec *spec = codec->spec;
9157 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9158 for (i = 0; i <= HDA_SIDE; i++) {
9159 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9160 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9162 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
9167 static void alc883_auto_init_hp_out(struct hda_codec *codec)
9169 struct alc_spec *spec = codec->spec;
9172 pin = spec->autocfg.hp_pins[0];
9173 if (pin) /* connect to front */
9175 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9176 pin = spec->autocfg.speaker_pins[0];
9178 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9181 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9182 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9184 static void alc883_auto_init_analog_input(struct hda_codec *codec)
9186 struct alc_spec *spec = codec->spec;
9189 for (i = 0; i < AUTO_PIN_LAST; i++) {
9190 hda_nid_t nid = spec->autocfg.input_pins[i];
9191 if (alc883_is_input_pin(nid)) {
9192 alc_set_input_pin(codec, nid, i);
9193 if (nid != ALC883_PIN_CD_NID &&
9194 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
9195 snd_hda_codec_write(codec, nid, 0,
9196 AC_VERB_SET_AMP_GAIN_MUTE,
9202 #define alc883_auto_init_input_src alc882_auto_init_input_src
9204 /* almost identical with ALC880 parser... */
9205 static int alc883_parse_auto_config(struct hda_codec *codec)
9207 struct alc_spec *spec = codec->spec;
9208 int err = alc880_parse_auto_config(codec);
9209 struct auto_pin_cfg *cfg = &spec->autocfg;
9215 return 0; /* no config found */
9217 err = alc_auto_add_mic_boost(codec);
9221 /* hack - override the init verbs */
9222 spec->init_verbs[0] = alc883_auto_init_verbs;
9224 /* setup input_mux for ALC889 */
9225 if (codec->vendor_id == 0x10ec0889) {
9226 /* digital-mic input pin is excluded in alc880_auto_create..()
9227 * because it's under 0x18
9229 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9230 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9231 struct hda_input_mux *imux = &spec->private_imux[0];
9232 for (i = 1; i < 3; i++)
9233 memcpy(&spec->private_imux[i],
9234 &spec->private_imux[0],
9235 sizeof(spec->private_imux[0]));
9236 imux->items[imux->num_items].label = "Int DMic";
9237 imux->items[imux->num_items].index = 0x0b;
9239 spec->num_mux_defs = 3;
9240 spec->input_mux = spec->private_imux;
9244 return 1; /* config found */
9247 /* additional initialization for auto-configuration model */
9248 static void alc883_auto_init(struct hda_codec *codec)
9250 struct alc_spec *spec = codec->spec;
9251 alc883_auto_init_multi_out(codec);
9252 alc883_auto_init_hp_out(codec);
9253 alc883_auto_init_analog_input(codec);
9254 alc883_auto_init_input_src(codec);
9255 if (spec->unsol_event)
9256 alc_inithook(codec);
9259 static int patch_alc883(struct hda_codec *codec)
9261 struct alc_spec *spec;
9262 int err, board_config;
9264 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9270 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9272 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9275 if (board_config < 0) {
9276 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
9277 "trying auto-probe from BIOS...\n");
9278 board_config = ALC883_AUTO;
9281 if (board_config == ALC883_AUTO) {
9282 /* automatic parse from the BIOS config */
9283 err = alc883_parse_auto_config(codec);
9289 "hda_codec: Cannot set up configuration "
9290 "from BIOS. Using base mode...\n");
9291 board_config = ALC883_3ST_2ch_DIG;
9295 err = snd_hda_attach_beep_device(codec, 0x1);
9301 if (board_config != ALC883_AUTO)
9302 setup_preset(spec, &alc883_presets[board_config]);
9304 switch (codec->vendor_id) {
9306 if (codec->revision_id == 0x100101) {
9307 spec->stream_name_analog = "ALC1200 Analog";
9308 spec->stream_name_digital = "ALC1200 Digital";
9310 spec->stream_name_analog = "ALC888 Analog";
9311 spec->stream_name_digital = "ALC888 Digital";
9313 if (!spec->num_adc_nids) {
9314 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9315 spec->adc_nids = alc883_adc_nids;
9317 if (!spec->capsrc_nids)
9318 spec->capsrc_nids = alc883_capsrc_nids;
9319 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9322 spec->stream_name_analog = "ALC889 Analog";
9323 spec->stream_name_digital = "ALC889 Digital";
9324 if (!spec->num_adc_nids) {
9325 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9326 spec->adc_nids = alc889_adc_nids;
9328 if (!spec->capsrc_nids)
9329 spec->capsrc_nids = alc889_capsrc_nids;
9330 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9334 spec->stream_name_analog = "ALC883 Analog";
9335 spec->stream_name_digital = "ALC883 Digital";
9336 if (!spec->num_adc_nids) {
9337 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9338 spec->adc_nids = alc883_adc_nids;
9340 if (!spec->capsrc_nids)
9341 spec->capsrc_nids = alc883_capsrc_nids;
9342 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9346 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9347 spec->stream_analog_capture = &alc883_pcm_analog_capture;
9348 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9350 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9351 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9353 if (!spec->cap_mixer)
9354 set_capture_mixer(spec);
9355 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9357 spec->vmaster_nid = 0x0c;
9359 codec->patch_ops = alc_patch_ops;
9360 if (board_config == ALC883_AUTO)
9361 spec->init_hook = alc883_auto_init;
9363 #ifdef CONFIG_SND_HDA_POWER_SAVE
9364 if (!spec->loopback.amplist)
9365 spec->loopback.amplist = alc883_loopbacks;
9367 codec->proc_widget_hook = print_realtek_coef;
9376 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9377 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
9379 #define alc262_dac_nids alc260_dac_nids
9380 #define alc262_adc_nids alc882_adc_nids
9381 #define alc262_adc_nids_alt alc882_adc_nids_alt
9382 #define alc262_capsrc_nids alc882_capsrc_nids
9383 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9385 #define alc262_modes alc260_modes
9386 #define alc262_capture_source alc882_capture_source
9388 static hda_nid_t alc262_dmic_adc_nids[1] = {
9393 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9395 static struct snd_kcontrol_new alc262_base_mixer[] = {
9396 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9397 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9398 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9399 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9400 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9401 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9403 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9404 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9405 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9406 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9407 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
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_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9411 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9415 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9416 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9417 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9418 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9419 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9420 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9421 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9422 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9423 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9424 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9425 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9426 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9427 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9428 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
9429 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9433 /* update HP, line and mono-out pins according to the master switch */
9434 static void alc262_hp_master_update(struct hda_codec *codec)
9436 struct alc_spec *spec = codec->spec;
9437 int val = spec->master_sw;
9440 snd_hda_codec_write_cache(codec, 0x1b, 0,
9441 AC_VERB_SET_PIN_WIDGET_CONTROL,
9443 snd_hda_codec_write_cache(codec, 0x15, 0,
9444 AC_VERB_SET_PIN_WIDGET_CONTROL,
9446 /* mono (speaker) depending on the HP jack sense */
9447 val = val && !spec->jack_present;
9448 snd_hda_codec_write_cache(codec, 0x16, 0,
9449 AC_VERB_SET_PIN_WIDGET_CONTROL,
9453 static void alc262_hp_bpc_automute(struct hda_codec *codec)
9455 struct alc_spec *spec = codec->spec;
9456 unsigned int presence;
9457 presence = snd_hda_codec_read(codec, 0x1b, 0,
9458 AC_VERB_GET_PIN_SENSE, 0);
9459 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9460 alc262_hp_master_update(codec);
9463 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9465 if ((res >> 26) != ALC880_HP_EVENT)
9467 alc262_hp_bpc_automute(codec);
9470 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9472 struct alc_spec *spec = codec->spec;
9473 unsigned int presence;
9474 presence = snd_hda_codec_read(codec, 0x15, 0,
9475 AC_VERB_GET_PIN_SENSE, 0);
9476 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9477 alc262_hp_master_update(codec);
9480 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9483 if ((res >> 26) != ALC880_HP_EVENT)
9485 alc262_hp_wildwest_automute(codec);
9488 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
9489 struct snd_ctl_elem_value *ucontrol)
9491 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9492 struct alc_spec *spec = codec->spec;
9493 *ucontrol->value.integer.value = spec->master_sw;
9497 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9498 struct snd_ctl_elem_value *ucontrol)
9500 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9501 struct alc_spec *spec = codec->spec;
9502 int val = !!*ucontrol->value.integer.value;
9504 if (val == spec->master_sw)
9506 spec->master_sw = val;
9507 alc262_hp_master_update(codec);
9511 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9514 .name = "Master Playback Switch",
9515 .info = snd_ctl_boolean_mono_info,
9516 .get = alc262_hp_master_sw_get,
9517 .put = alc262_hp_master_sw_put,
9519 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9520 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9521 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9522 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9524 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9526 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9527 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9528 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9529 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9530 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9531 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9532 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9533 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9534 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9535 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9536 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9537 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9541 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9543 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9544 .name = "Master Playback Switch",
9545 .info = snd_ctl_boolean_mono_info,
9546 .get = alc262_hp_master_sw_get,
9547 .put = alc262_hp_master_sw_put,
9549 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9550 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9551 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9552 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9553 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9555 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9557 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9558 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9559 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9560 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9561 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9562 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9563 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9567 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9568 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9569 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9570 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9574 /* mute/unmute internal speaker according to the hp jack and mute state */
9575 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9577 struct alc_spec *spec = codec->spec;
9579 if (force || !spec->sense_updated) {
9580 unsigned int present;
9581 present = snd_hda_codec_read(codec, 0x15, 0,
9582 AC_VERB_GET_PIN_SENSE, 0);
9583 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9584 spec->sense_updated = 1;
9586 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9587 spec->jack_present ? HDA_AMP_MUTE : 0);
9590 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9593 if ((res >> 26) != ALC880_HP_EVENT)
9595 alc262_hp_t5735_automute(codec, 1);
9598 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9600 alc262_hp_t5735_automute(codec, 1);
9603 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9604 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9605 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9606 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9607 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9608 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9609 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9610 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9614 static struct hda_verb alc262_hp_t5735_verbs[] = {
9615 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9616 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9618 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9622 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9623 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9624 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9625 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9626 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9627 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9628 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9632 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9633 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9634 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9635 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9636 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9637 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9638 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9639 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9640 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9641 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9642 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9646 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9653 /* bind hp and internal speaker mute (with plug check) */
9654 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9655 struct snd_ctl_elem_value *ucontrol)
9657 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9658 long *valp = ucontrol->value.integer.value;
9661 /* change hp mute */
9662 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9664 valp[0] ? 0 : HDA_AMP_MUTE);
9665 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9667 valp[1] ? 0 : HDA_AMP_MUTE);
9669 /* change speaker according to HP jack state */
9670 struct alc_spec *spec = codec->spec;
9672 if (spec->jack_present)
9673 mute = HDA_AMP_MUTE;
9675 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9677 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9678 HDA_AMP_MUTE, mute);
9683 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9684 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9686 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9687 .name = "Master Playback Switch",
9688 .info = snd_hda_mixer_amp_switch_info,
9689 .get = snd_hda_mixer_amp_switch_get,
9690 .put = alc262_sony_master_sw_put,
9691 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9693 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9694 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9695 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9696 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9700 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9701 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9702 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9703 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9704 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9705 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9706 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9707 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9711 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9712 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9713 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9714 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9715 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9716 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9717 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9718 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9719 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9720 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9721 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9722 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9723 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9727 static struct hda_verb alc262_tyan_verbs[] = {
9728 /* Headphone automute */
9729 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9730 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9731 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9733 /* P11 AUX_IN, white 4-pin connector */
9734 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9735 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9736 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9737 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9742 /* unsolicited event for HP jack sensing */
9743 static void alc262_tyan_automute(struct hda_codec *codec)
9746 unsigned int present;
9748 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9749 present = snd_hda_codec_read(codec, 0x1b, 0,
9750 AC_VERB_GET_PIN_SENSE, 0);
9751 present = (present & 0x80000000) != 0;
9753 /* mute line output on ATX panel */
9754 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9755 HDA_AMP_MUTE, HDA_AMP_MUTE);
9757 /* unmute line output if necessary */
9758 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9759 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9760 HDA_AMP_MUTE, mute);
9764 static void alc262_tyan_unsol_event(struct hda_codec *codec,
9767 if ((res >> 26) != ALC880_HP_EVENT)
9769 alc262_tyan_automute(codec);
9772 #define alc262_capture_mixer alc882_capture_mixer
9773 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9776 * generic initialization of ADC, input mixers and output mixers
9778 static struct hda_verb alc262_init_verbs[] = {
9780 * Unmute ADC0-2 and set the default input to mic-in
9782 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9783 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9784 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9785 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9786 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9787 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9789 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9791 * Note: PASD motherboards uses the Line In 2 as the input for
9792 * front panel mic (mic 2)
9794 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9795 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9796 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9797 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9798 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9799 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9802 * Set up output mixers (0x0c - 0x0e)
9804 /* set vol=0 to output mixers */
9805 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9807 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9808 /* set up input amps for analog loopback */
9809 /* Amp Indices: DAC = 0, mixer = 1 */
9810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9812 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9813 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9814 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9815 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9817 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9818 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9819 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9820 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9821 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9822 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9824 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9826 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9827 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9828 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9830 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9831 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9833 /* FIXME: use matrix-type input source selection */
9834 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9835 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9836 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9837 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9838 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9839 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9841 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9842 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9843 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9844 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9846 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9847 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9848 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9849 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9854 static struct hda_verb alc262_eapd_verbs[] = {
9855 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9856 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9860 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9861 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9862 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9866 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9867 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9868 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9869 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9871 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9872 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9876 static struct hda_verb alc262_sony_unsol_verbs[] = {
9877 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9878 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9879 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9881 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9882 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9886 static struct hda_input_mux alc262_dmic_capture_source = {
9889 { "Int DMic", 0x9 },
9894 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9895 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9896 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9897 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9903 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9904 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9905 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9906 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9907 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9908 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9909 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9910 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9911 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9915 static void alc262_dmic_automute(struct hda_codec *codec)
9917 unsigned int present;
9919 present = snd_hda_codec_read(codec, 0x18, 0,
9920 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9921 snd_hda_codec_write(codec, 0x22, 0,
9922 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9925 /* toggle speaker-output according to the hp-jack state */
9926 static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9928 unsigned int present;
9931 present = snd_hda_codec_read(codec, 0x15, 0,
9932 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9933 bits = present ? 0 : PIN_OUT;
9934 snd_hda_codec_write(codec, 0x14, 0,
9935 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9940 /* unsolicited event for HP jack sensing */
9941 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9944 if ((res >> 26) == ALC880_HP_EVENT)
9945 alc262_toshiba_s06_speaker_automute(codec);
9946 if ((res >> 26) == ALC880_MIC_EVENT)
9947 alc262_dmic_automute(codec);
9951 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9953 alc262_toshiba_s06_speaker_automute(codec);
9954 alc262_dmic_automute(codec);
9957 /* mute/unmute internal speaker according to the hp jack and mute state */
9958 static void alc262_hippo_automute(struct hda_codec *codec)
9960 struct alc_spec *spec = codec->spec;
9962 unsigned int present;
9964 /* need to execute and sync at first */
9965 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9966 present = snd_hda_codec_read(codec, 0x15, 0,
9967 AC_VERB_GET_PIN_SENSE, 0);
9968 spec->jack_present = (present & 0x80000000) != 0;
9969 if (spec->jack_present) {
9970 /* mute internal speaker */
9971 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9972 HDA_AMP_MUTE, HDA_AMP_MUTE);
9974 /* unmute internal speaker if necessary */
9975 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9976 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9977 HDA_AMP_MUTE, mute);
9981 /* unsolicited event for HP jack sensing */
9982 static void alc262_hippo_unsol_event(struct hda_codec *codec,
9985 if ((res >> 26) != ALC880_HP_EVENT)
9987 alc262_hippo_automute(codec);
9990 static void alc262_hippo1_automute(struct hda_codec *codec)
9993 unsigned int present;
9995 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9996 present = snd_hda_codec_read(codec, 0x1b, 0,
9997 AC_VERB_GET_PIN_SENSE, 0);
9998 present = (present & 0x80000000) != 0;
10000 /* mute internal speaker */
10001 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10002 HDA_AMP_MUTE, HDA_AMP_MUTE);
10004 /* unmute internal speaker if necessary */
10005 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10006 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10007 HDA_AMP_MUTE, mute);
10011 /* unsolicited event for HP jack sensing */
10012 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
10015 if ((res >> 26) != ALC880_HP_EVENT)
10017 alc262_hippo1_automute(codec);
10023 * 0x16 = internal speaker
10024 * 0x18 = external mic
10027 static struct snd_kcontrol_new alc262_nec_mixer[] = {
10028 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10029 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10031 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10032 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10033 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10035 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10036 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10040 static struct hda_verb alc262_nec_verbs[] = {
10041 /* Unmute Speaker */
10042 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10045 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10046 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10048 /* External mic to headphone */
10049 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10050 /* External mic to speaker */
10051 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10057 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10058 * 0x1b = port replicator headphone out
10061 #define ALC_HP_EVENT 0x37
10063 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10064 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10065 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10066 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10067 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10071 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10072 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10073 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10077 static struct hda_input_mux alc262_fujitsu_capture_source = {
10081 { "Int Mic", 0x1 },
10086 static struct hda_input_mux alc262_HP_capture_source = {
10090 { "Front Mic", 0x1 },
10097 static struct hda_input_mux alc262_HP_D7000_capture_source = {
10101 { "Front Mic", 0x2 },
10107 /* mute/unmute internal speaker according to the hp jacks and mute state */
10108 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10110 struct alc_spec *spec = codec->spec;
10113 if (force || !spec->sense_updated) {
10114 unsigned int present;
10115 /* need to execute and sync at first */
10116 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
10117 /* check laptop HP jack */
10118 present = snd_hda_codec_read(codec, 0x14, 0,
10119 AC_VERB_GET_PIN_SENSE, 0);
10120 /* need to execute and sync at first */
10121 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10122 /* check docking HP jack */
10123 present |= snd_hda_codec_read(codec, 0x1b, 0,
10124 AC_VERB_GET_PIN_SENSE, 0);
10125 if (present & AC_PINSENSE_PRESENCE)
10126 spec->jack_present = 1;
10128 spec->jack_present = 0;
10129 spec->sense_updated = 1;
10131 /* unmute internal speaker only if both HPs are unplugged and
10132 * master switch is on
10134 if (spec->jack_present)
10135 mute = HDA_AMP_MUTE;
10137 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10138 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10139 HDA_AMP_MUTE, mute);
10142 /* unsolicited event for HP jack sensing */
10143 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10146 if ((res >> 26) != ALC_HP_EVENT)
10148 alc262_fujitsu_automute(codec, 1);
10151 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10153 alc262_fujitsu_automute(codec, 1);
10156 /* bind volumes of both NID 0x0c and 0x0d */
10157 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10158 .ops = &snd_hda_bind_vol,
10160 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10161 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10166 /* mute/unmute internal speaker according to the hp jack and mute state */
10167 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10169 struct alc_spec *spec = codec->spec;
10172 if (force || !spec->sense_updated) {
10173 unsigned int present_int_hp;
10174 /* need to execute and sync at first */
10175 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10176 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10177 AC_VERB_GET_PIN_SENSE, 0);
10178 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10179 spec->sense_updated = 1;
10181 if (spec->jack_present) {
10182 /* mute internal speaker */
10183 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10184 HDA_AMP_MUTE, HDA_AMP_MUTE);
10185 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10186 HDA_AMP_MUTE, HDA_AMP_MUTE);
10188 /* unmute internal speaker if necessary */
10189 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10190 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10191 HDA_AMP_MUTE, mute);
10192 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10193 HDA_AMP_MUTE, mute);
10197 /* unsolicited event for HP jack sensing */
10198 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10201 if ((res >> 26) != ALC_HP_EVENT)
10203 alc262_lenovo_3000_automute(codec, 1);
10206 /* bind hp and internal speaker mute (with plug check) */
10207 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10208 struct snd_ctl_elem_value *ucontrol)
10210 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10211 long *valp = ucontrol->value.integer.value;
10214 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10216 valp ? 0 : HDA_AMP_MUTE);
10217 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10219 valp ? 0 : HDA_AMP_MUTE);
10222 alc262_fujitsu_automute(codec, 0);
10226 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10227 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10229 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10230 .name = "Master Playback Switch",
10231 .info = snd_hda_mixer_amp_switch_info,
10232 .get = snd_hda_mixer_amp_switch_get,
10233 .put = alc262_fujitsu_master_sw_put,
10234 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10236 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10237 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10238 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10239 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10240 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10241 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10242 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10243 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10247 /* bind hp and internal speaker mute (with plug check) */
10248 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10249 struct snd_ctl_elem_value *ucontrol)
10251 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10252 long *valp = ucontrol->value.integer.value;
10255 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10257 valp ? 0 : HDA_AMP_MUTE);
10260 alc262_lenovo_3000_automute(codec, 0);
10264 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10265 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10267 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10268 .name = "Master Playback Switch",
10269 .info = snd_hda_mixer_amp_switch_info,
10270 .get = snd_hda_mixer_amp_switch_get,
10271 .put = alc262_lenovo_3000_master_sw_put,
10272 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10274 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10275 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10276 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10277 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10278 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10279 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10280 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10281 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10285 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10286 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10288 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10289 .name = "Master Playback Switch",
10290 .info = snd_hda_mixer_amp_switch_info,
10291 .get = snd_hda_mixer_amp_switch_get,
10292 .put = alc262_sony_master_sw_put,
10293 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
10295 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10296 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10297 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10298 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10299 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10300 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10304 /* additional init verbs for Benq laptops */
10305 static struct hda_verb alc262_EAPD_verbs[] = {
10306 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10307 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10311 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10312 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10313 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10315 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10316 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10320 /* Samsung Q1 Ultra Vista model setup */
10321 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10322 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10323 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10324 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10325 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10326 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10327 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10331 static struct hda_verb alc262_ultra_verbs[] = {
10333 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10334 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10335 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10337 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10338 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10339 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10340 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10343 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10344 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10345 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10346 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10348 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10349 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10350 /* ADC, choose mic */
10351 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10352 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10354 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10360 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10364 /* mute/unmute internal speaker according to the hp jack and mute state */
10365 static void alc262_ultra_automute(struct hda_codec *codec)
10367 struct alc_spec *spec = codec->spec;
10371 /* auto-mute only when HP is used as HP */
10372 if (!spec->cur_mux[0]) {
10373 unsigned int present;
10374 /* need to execute and sync at first */
10375 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10376 present = snd_hda_codec_read(codec, 0x15, 0,
10377 AC_VERB_GET_PIN_SENSE, 0);
10378 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10379 if (spec->jack_present)
10380 mute = HDA_AMP_MUTE;
10382 /* mute/unmute internal speaker */
10383 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10384 HDA_AMP_MUTE, mute);
10385 /* mute/unmute HP */
10386 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10387 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10390 /* unsolicited event for HP jack sensing */
10391 static void alc262_ultra_unsol_event(struct hda_codec *codec,
10394 if ((res >> 26) != ALC880_HP_EVENT)
10396 alc262_ultra_automute(codec);
10399 static struct hda_input_mux alc262_ultra_capture_source = {
10403 { "Headphone", 0x7 },
10407 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10408 struct snd_ctl_elem_value *ucontrol)
10410 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10411 struct alc_spec *spec = codec->spec;
10414 ret = alc_mux_enum_put(kcontrol, ucontrol);
10417 /* reprogram the HP pin as mic or HP according to the input source */
10418 snd_hda_codec_write_cache(codec, 0x15, 0,
10419 AC_VERB_SET_PIN_WIDGET_CONTROL,
10420 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10421 alc262_ultra_automute(codec); /* mute/unmute HP */
10425 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10426 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10427 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10429 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10430 .name = "Capture Source",
10431 .info = alc_mux_enum_info,
10432 .get = alc_mux_enum_get,
10433 .put = alc262_ultra_mux_enum_put,
10438 /* add playback controls from the parsed DAC table */
10439 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10440 const struct auto_pin_cfg *cfg)
10445 spec->multiout.num_dacs = 1; /* only use one dac */
10446 spec->multiout.dac_nids = spec->private_dac_nids;
10447 spec->multiout.dac_nids[0] = 2;
10449 nid = cfg->line_out_pins[0];
10451 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10452 "Front Playback Volume",
10453 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10456 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10457 "Front Playback Switch",
10458 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10463 nid = cfg->speaker_pins[0];
10466 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10467 "Speaker Playback Volume",
10468 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10472 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10473 "Speaker Playback Switch",
10474 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10479 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10480 "Speaker Playback Switch",
10481 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10487 nid = cfg->hp_pins[0];
10489 /* spec->multiout.hp_nid = 2; */
10491 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10492 "Headphone Playback Volume",
10493 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10497 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10498 "Headphone Playback Switch",
10499 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10504 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10505 "Headphone Playback Switch",
10506 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10515 /* identical with ALC880 */
10516 #define alc262_auto_create_analog_input_ctls \
10517 alc880_auto_create_analog_input_ctls
10520 * generic initialization of ADC, input mixers and output mixers
10522 static struct hda_verb alc262_volume_init_verbs[] = {
10524 * Unmute ADC0-2 and set the default input to mic-in
10526 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10527 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10528 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10529 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10530 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10531 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10533 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10535 * Note: PASD motherboards uses the Line In 2 as the input for
10536 * front panel mic (mic 2)
10538 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10539 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10546 * Set up output mixers (0x0c - 0x0f)
10548 /* set vol=0 to output mixers */
10549 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10550 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10551 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10553 /* set up input amps for analog loopback */
10554 /* Amp Indices: DAC = 0, mixer = 1 */
10555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10557 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10558 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10559 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10560 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10562 /* FIXME: use matrix-type input source selection */
10563 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10564 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10565 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10566 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10567 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10568 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10570 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10571 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10572 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10573 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10575 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10576 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10577 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10578 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10583 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10585 * Unmute ADC0-2 and set the default input to mic-in
10587 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10588 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10589 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10590 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10591 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10592 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10594 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10596 * Note: PASD motherboards uses the Line In 2 as the input for
10597 * front panel mic (mic 2)
10599 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10600 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10601 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10603 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10604 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10605 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10606 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10609 * Set up output mixers (0x0c - 0x0e)
10611 /* set vol=0 to output mixers */
10612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10613 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10614 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10616 /* set up input amps for analog loopback */
10617 /* Amp Indices: DAC = 0, mixer = 1 */
10618 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10619 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10620 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10621 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10622 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10623 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10625 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10626 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10627 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10629 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10630 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10632 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10633 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10635 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10636 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10637 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10638 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10639 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10641 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10642 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10643 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10644 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10645 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10646 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10649 /* FIXME: use matrix-type input source selection */
10650 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10651 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10652 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10653 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10654 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10655 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10657 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10658 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10659 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10660 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10662 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10664 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10665 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10667 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10672 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10674 * Unmute ADC0-2 and set the default input to mic-in
10676 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10677 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10678 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10679 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10680 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10681 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10683 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10685 * Note: PASD motherboards uses the Line In 2 as the input for front
10686 * panel mic (mic 2)
10688 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10691 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10692 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10693 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10694 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10695 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10696 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10698 * Set up output mixers (0x0c - 0x0e)
10700 /* set vol=0 to output mixers */
10701 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10702 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10703 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10705 /* set up input amps for analog loopback */
10706 /* Amp Indices: DAC = 0, mixer = 1 */
10707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10708 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10709 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10710 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10711 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10712 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10715 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10716 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10717 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10718 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10719 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10720 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10721 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10723 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10724 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10726 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10727 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10729 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10730 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10731 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10732 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10733 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10734 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10736 /* FIXME: use matrix-type input source selection */
10737 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10738 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10739 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10740 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10741 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10742 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10743 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10744 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10745 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10747 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10748 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10749 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10750 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10751 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10752 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10753 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10755 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10756 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10757 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10758 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10759 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10760 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10761 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10763 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10768 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10770 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10771 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10772 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10774 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10775 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10776 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10777 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10779 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10780 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10781 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10786 #ifdef CONFIG_SND_HDA_POWER_SAVE
10787 #define alc262_loopbacks alc880_loopbacks
10790 /* pcm configuration: identiacal with ALC880 */
10791 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10792 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10793 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10794 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10797 * BIOS auto configuration
10799 static int alc262_parse_auto_config(struct hda_codec *codec)
10801 struct alc_spec *spec = codec->spec;
10803 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10805 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10809 if (!spec->autocfg.line_outs) {
10810 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
10811 spec->multiout.max_channels = 2;
10812 spec->no_analog = 1;
10815 return 0; /* can't find valid BIOS pin config */
10817 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10820 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10824 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10827 if (spec->autocfg.dig_outs) {
10828 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10829 spec->dig_out_type = spec->autocfg.dig_out_type[0];
10831 if (spec->autocfg.dig_in_pin)
10832 spec->dig_in_nid = ALC262_DIGIN_NID;
10834 if (spec->kctls.list)
10835 add_mixer(spec, spec->kctls.list);
10837 add_verb(spec, alc262_volume_init_verbs);
10838 spec->num_mux_defs = 1;
10839 spec->input_mux = &spec->private_imux[0];
10841 err = alc_auto_add_mic_boost(codec);
10848 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10849 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10850 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10851 #define alc262_auto_init_input_src alc882_auto_init_input_src
10854 /* init callback for auto-configuration model -- overriding the default init */
10855 static void alc262_auto_init(struct hda_codec *codec)
10857 struct alc_spec *spec = codec->spec;
10858 alc262_auto_init_multi_out(codec);
10859 alc262_auto_init_hp_out(codec);
10860 alc262_auto_init_analog_input(codec);
10861 alc262_auto_init_input_src(codec);
10862 if (spec->unsol_event)
10863 alc_inithook(codec);
10867 * configuration and preset
10869 static const char *alc262_models[ALC262_MODEL_LAST] = {
10870 [ALC262_BASIC] = "basic",
10871 [ALC262_HIPPO] = "hippo",
10872 [ALC262_HIPPO_1] = "hippo_1",
10873 [ALC262_FUJITSU] = "fujitsu",
10874 [ALC262_HP_BPC] = "hp-bpc",
10875 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10876 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10877 [ALC262_HP_RP5700] = "hp-rp5700",
10878 [ALC262_BENQ_ED8] = "benq",
10879 [ALC262_BENQ_T31] = "benq-t31",
10880 [ALC262_SONY_ASSAMD] = "sony-assamd",
10881 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10882 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10883 [ALC262_ULTRA] = "ultra",
10884 [ALC262_LENOVO_3000] = "lenovo-3000",
10885 [ALC262_NEC] = "nec",
10886 [ALC262_TYAN] = "tyan",
10887 [ALC262_AUTO] = "auto",
10890 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10891 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10892 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10893 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10895 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10897 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
10899 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10900 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10901 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10902 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10903 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10904 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10905 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10906 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10907 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10908 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10909 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10910 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10911 ALC262_HP_TC_T5735),
10912 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10913 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10914 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10915 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10916 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
10917 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
10918 ALC262_SONY_ASSAMD),
10919 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10920 ALC262_TOSHIBA_RX1),
10921 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10922 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10923 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10924 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
10925 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10927 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
10928 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10929 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10930 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10931 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10935 static struct alc_config_preset alc262_presets[] = {
10937 .mixers = { alc262_base_mixer },
10938 .init_verbs = { alc262_init_verbs },
10939 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10940 .dac_nids = alc262_dac_nids,
10942 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10943 .channel_mode = alc262_modes,
10944 .input_mux = &alc262_capture_source,
10947 .mixers = { alc262_base_mixer },
10948 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10949 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10950 .dac_nids = alc262_dac_nids,
10952 .dig_out_nid = ALC262_DIGOUT_NID,
10953 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10954 .channel_mode = alc262_modes,
10955 .input_mux = &alc262_capture_source,
10956 .unsol_event = alc262_hippo_unsol_event,
10957 .init_hook = alc262_hippo_automute,
10959 [ALC262_HIPPO_1] = {
10960 .mixers = { alc262_hippo1_mixer },
10961 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10962 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10963 .dac_nids = alc262_dac_nids,
10965 .dig_out_nid = ALC262_DIGOUT_NID,
10966 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10967 .channel_mode = alc262_modes,
10968 .input_mux = &alc262_capture_source,
10969 .unsol_event = alc262_hippo1_unsol_event,
10970 .init_hook = alc262_hippo1_automute,
10972 [ALC262_FUJITSU] = {
10973 .mixers = { alc262_fujitsu_mixer },
10974 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10975 alc262_fujitsu_unsol_verbs },
10976 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10977 .dac_nids = alc262_dac_nids,
10979 .dig_out_nid = ALC262_DIGOUT_NID,
10980 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10981 .channel_mode = alc262_modes,
10982 .input_mux = &alc262_fujitsu_capture_source,
10983 .unsol_event = alc262_fujitsu_unsol_event,
10984 .init_hook = alc262_fujitsu_init_hook,
10986 [ALC262_HP_BPC] = {
10987 .mixers = { alc262_HP_BPC_mixer },
10988 .init_verbs = { alc262_HP_BPC_init_verbs },
10989 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10990 .dac_nids = alc262_dac_nids,
10992 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10993 .channel_mode = alc262_modes,
10994 .input_mux = &alc262_HP_capture_source,
10995 .unsol_event = alc262_hp_bpc_unsol_event,
10996 .init_hook = alc262_hp_bpc_automute,
10998 [ALC262_HP_BPC_D7000_WF] = {
10999 .mixers = { alc262_HP_BPC_WildWest_mixer },
11000 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11001 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11002 .dac_nids = alc262_dac_nids,
11004 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11005 .channel_mode = alc262_modes,
11006 .input_mux = &alc262_HP_D7000_capture_source,
11007 .unsol_event = alc262_hp_wildwest_unsol_event,
11008 .init_hook = alc262_hp_wildwest_automute,
11010 [ALC262_HP_BPC_D7000_WL] = {
11011 .mixers = { alc262_HP_BPC_WildWest_mixer,
11012 alc262_HP_BPC_WildWest_option_mixer },
11013 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11014 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11015 .dac_nids = alc262_dac_nids,
11017 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11018 .channel_mode = alc262_modes,
11019 .input_mux = &alc262_HP_D7000_capture_source,
11020 .unsol_event = alc262_hp_wildwest_unsol_event,
11021 .init_hook = alc262_hp_wildwest_automute,
11023 [ALC262_HP_TC_T5735] = {
11024 .mixers = { alc262_hp_t5735_mixer },
11025 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11026 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11027 .dac_nids = alc262_dac_nids,
11029 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11030 .channel_mode = alc262_modes,
11031 .input_mux = &alc262_capture_source,
11032 .unsol_event = alc262_hp_t5735_unsol_event,
11033 .init_hook = alc262_hp_t5735_init_hook,
11035 [ALC262_HP_RP5700] = {
11036 .mixers = { alc262_hp_rp5700_mixer },
11037 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11038 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11039 .dac_nids = alc262_dac_nids,
11040 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11041 .channel_mode = alc262_modes,
11042 .input_mux = &alc262_hp_rp5700_capture_source,
11044 [ALC262_BENQ_ED8] = {
11045 .mixers = { alc262_base_mixer },
11046 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11047 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11048 .dac_nids = alc262_dac_nids,
11050 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11051 .channel_mode = alc262_modes,
11052 .input_mux = &alc262_capture_source,
11054 [ALC262_SONY_ASSAMD] = {
11055 .mixers = { alc262_sony_mixer },
11056 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11057 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11058 .dac_nids = alc262_dac_nids,
11060 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11061 .channel_mode = alc262_modes,
11062 .input_mux = &alc262_capture_source,
11063 .unsol_event = alc262_hippo_unsol_event,
11064 .init_hook = alc262_hippo_automute,
11066 [ALC262_BENQ_T31] = {
11067 .mixers = { alc262_benq_t31_mixer },
11068 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
11069 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11070 .dac_nids = alc262_dac_nids,
11072 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11073 .channel_mode = alc262_modes,
11074 .input_mux = &alc262_capture_source,
11075 .unsol_event = alc262_hippo_unsol_event,
11076 .init_hook = alc262_hippo_automute,
11079 .mixers = { alc262_ultra_mixer },
11080 .cap_mixer = alc262_ultra_capture_mixer,
11081 .init_verbs = { alc262_ultra_verbs },
11082 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11083 .dac_nids = alc262_dac_nids,
11084 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11085 .channel_mode = alc262_modes,
11086 .input_mux = &alc262_ultra_capture_source,
11087 .adc_nids = alc262_adc_nids, /* ADC0 */
11088 .capsrc_nids = alc262_capsrc_nids,
11089 .num_adc_nids = 1, /* single ADC */
11090 .unsol_event = alc262_ultra_unsol_event,
11091 .init_hook = alc262_ultra_automute,
11093 [ALC262_LENOVO_3000] = {
11094 .mixers = { alc262_lenovo_3000_mixer },
11095 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11096 alc262_lenovo_3000_unsol_verbs },
11097 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11098 .dac_nids = alc262_dac_nids,
11100 .dig_out_nid = ALC262_DIGOUT_NID,
11101 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11102 .channel_mode = alc262_modes,
11103 .input_mux = &alc262_fujitsu_capture_source,
11104 .unsol_event = alc262_lenovo_3000_unsol_event,
11107 .mixers = { alc262_nec_mixer },
11108 .init_verbs = { alc262_nec_verbs },
11109 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11110 .dac_nids = alc262_dac_nids,
11112 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11113 .channel_mode = alc262_modes,
11114 .input_mux = &alc262_capture_source,
11116 [ALC262_TOSHIBA_S06] = {
11117 .mixers = { alc262_toshiba_s06_mixer },
11118 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11119 alc262_eapd_verbs },
11120 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11121 .capsrc_nids = alc262_dmic_capsrc_nids,
11122 .dac_nids = alc262_dac_nids,
11123 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11124 .dig_out_nid = ALC262_DIGOUT_NID,
11125 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11126 .channel_mode = alc262_modes,
11127 .input_mux = &alc262_dmic_capture_source,
11128 .unsol_event = alc262_toshiba_s06_unsol_event,
11129 .init_hook = alc262_toshiba_s06_init_hook,
11131 [ALC262_TOSHIBA_RX1] = {
11132 .mixers = { alc262_toshiba_rx1_mixer },
11133 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11134 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11135 .dac_nids = alc262_dac_nids,
11137 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11138 .channel_mode = alc262_modes,
11139 .input_mux = &alc262_capture_source,
11140 .unsol_event = alc262_hippo_unsol_event,
11141 .init_hook = alc262_hippo_automute,
11144 .mixers = { alc262_tyan_mixer },
11145 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11146 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11147 .dac_nids = alc262_dac_nids,
11149 .dig_out_nid = ALC262_DIGOUT_NID,
11150 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11151 .channel_mode = alc262_modes,
11152 .input_mux = &alc262_capture_source,
11153 .unsol_event = alc262_tyan_unsol_event,
11154 .init_hook = alc262_tyan_automute,
11158 static int patch_alc262(struct hda_codec *codec)
11160 struct alc_spec *spec;
11164 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11168 codec->spec = spec;
11170 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11175 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11176 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11177 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11178 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11182 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11184 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11188 if (board_config < 0) {
11189 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
11190 "trying auto-probe from BIOS...\n");
11191 board_config = ALC262_AUTO;
11194 if (board_config == ALC262_AUTO) {
11195 /* automatic parse from the BIOS config */
11196 err = alc262_parse_auto_config(codec);
11202 "hda_codec: Cannot set up configuration "
11203 "from BIOS. Using base mode...\n");
11204 board_config = ALC262_BASIC;
11208 if (!spec->no_analog) {
11209 err = snd_hda_attach_beep_device(codec, 0x1);
11216 if (board_config != ALC262_AUTO)
11217 setup_preset(spec, &alc262_presets[board_config]);
11219 spec->stream_name_analog = "ALC262 Analog";
11220 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11221 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11223 spec->stream_name_digital = "ALC262 Digital";
11224 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11225 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11227 spec->capture_style = CAPT_MIX;
11228 if (!spec->adc_nids && spec->input_mux) {
11229 /* check whether NID 0x07 is valid */
11230 unsigned int wcap = get_wcaps(codec, 0x07);
11233 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11234 if (wcap != AC_WID_AUD_IN) {
11235 spec->adc_nids = alc262_adc_nids_alt;
11236 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
11237 spec->capsrc_nids = alc262_capsrc_nids_alt;
11239 spec->adc_nids = alc262_adc_nids;
11240 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
11241 spec->capsrc_nids = alc262_capsrc_nids;
11244 if (!spec->cap_mixer && !spec->no_analog)
11245 set_capture_mixer(spec);
11246 if (!spec->no_analog)
11247 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11249 spec->vmaster_nid = 0x0c;
11251 codec->patch_ops = alc_patch_ops;
11252 if (board_config == ALC262_AUTO)
11253 spec->init_hook = alc262_auto_init;
11254 #ifdef CONFIG_SND_HDA_POWER_SAVE
11255 if (!spec->loopback.amplist)
11256 spec->loopback.amplist = alc262_loopbacks;
11258 codec->proc_widget_hook = print_realtek_coef;
11264 * ALC268 channel source setting (2 channel)
11266 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11267 #define alc268_modes alc260_modes
11269 static hda_nid_t alc268_dac_nids[2] = {
11274 static hda_nid_t alc268_adc_nids[2] = {
11279 static hda_nid_t alc268_adc_nids_alt[1] = {
11284 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11286 static struct snd_kcontrol_new alc268_base_mixer[] = {
11287 /* output mixer control */
11288 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11289 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11290 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11291 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11292 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11293 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11294 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11298 /* bind Beep switches of both NID 0x0f and 0x10 */
11299 static struct hda_bind_ctls alc268_bind_beep_sw = {
11300 .ops = &snd_hda_bind_sw,
11302 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11303 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11308 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11309 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11310 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11314 static struct hda_verb alc268_eapd_verbs[] = {
11315 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11316 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11320 /* Toshiba specific */
11321 #define alc268_toshiba_automute alc262_hippo_automute
11323 static struct hda_verb alc268_toshiba_verbs[] = {
11324 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11328 static struct hda_input_mux alc268_acer_lc_capture_source = {
11336 /* Acer specific */
11337 /* bind volumes of both NID 0x02 and 0x03 */
11338 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11339 .ops = &snd_hda_bind_vol,
11341 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11342 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11347 /* mute/unmute internal speaker according to the hp jack and mute state */
11348 static void alc268_acer_automute(struct hda_codec *codec, int force)
11350 struct alc_spec *spec = codec->spec;
11353 if (force || !spec->sense_updated) {
11354 unsigned int present;
11355 present = snd_hda_codec_read(codec, 0x14, 0,
11356 AC_VERB_GET_PIN_SENSE, 0);
11357 spec->jack_present = (present & 0x80000000) != 0;
11358 spec->sense_updated = 1;
11360 if (spec->jack_present)
11361 mute = HDA_AMP_MUTE; /* mute internal speaker */
11362 else /* unmute internal speaker if necessary */
11363 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11364 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11365 HDA_AMP_MUTE, mute);
11369 /* bind hp and internal speaker mute (with plug check) */
11370 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11371 struct snd_ctl_elem_value *ucontrol)
11373 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11374 long *valp = ucontrol->value.integer.value;
11377 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11379 valp[0] ? 0 : HDA_AMP_MUTE);
11380 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11382 valp[1] ? 0 : HDA_AMP_MUTE);
11384 alc268_acer_automute(codec, 0);
11388 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11389 /* output mixer control */
11390 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11392 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11393 .name = "Master Playback Switch",
11394 .info = snd_hda_mixer_amp_switch_info,
11395 .get = snd_hda_mixer_amp_switch_get,
11396 .put = alc268_acer_master_sw_put,
11397 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11399 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11403 static struct snd_kcontrol_new alc268_acer_mixer[] = {
11404 /* output mixer control */
11405 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11407 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11408 .name = "Master Playback Switch",
11409 .info = snd_hda_mixer_amp_switch_info,
11410 .get = snd_hda_mixer_amp_switch_get,
11411 .put = alc268_acer_master_sw_put,
11412 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11414 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11415 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11416 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11420 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11421 /* output mixer control */
11422 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11424 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11425 .name = "Master Playback Switch",
11426 .info = snd_hda_mixer_amp_switch_info,
11427 .get = snd_hda_mixer_amp_switch_get,
11428 .put = alc268_acer_master_sw_put,
11429 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11431 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11432 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11436 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11437 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11438 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11439 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11440 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11441 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11442 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11446 static struct hda_verb alc268_acer_verbs[] = {
11447 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11448 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11449 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11450 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11451 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11452 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11453 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11457 /* unsolicited event for HP jack sensing */
11458 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
11461 if ((res >> 26) != ALC880_HP_EVENT)
11463 alc268_toshiba_automute(codec);
11466 static void alc268_acer_unsol_event(struct hda_codec *codec,
11469 if ((res >> 26) != ALC880_HP_EVENT)
11471 alc268_acer_automute(codec, 1);
11474 static void alc268_acer_init_hook(struct hda_codec *codec)
11476 alc268_acer_automute(codec, 1);
11479 /* toggle speaker-output according to the hp-jack state */
11480 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11482 unsigned int present;
11483 unsigned char bits;
11485 present = snd_hda_codec_read(codec, 0x15, 0,
11486 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11487 bits = present ? AMP_IN_MUTE(0) : 0;
11488 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11489 AMP_IN_MUTE(0), bits);
11490 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11491 AMP_IN_MUTE(0), bits);
11495 static void alc268_acer_mic_automute(struct hda_codec *codec)
11497 unsigned int present;
11499 present = snd_hda_codec_read(codec, 0x18, 0,
11500 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11501 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11502 present ? 0x0 : 0x6);
11505 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11508 if ((res >> 26) == ALC880_HP_EVENT)
11509 alc268_aspire_one_speaker_automute(codec);
11510 if ((res >> 26) == ALC880_MIC_EVENT)
11511 alc268_acer_mic_automute(codec);
11514 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11516 alc268_aspire_one_speaker_automute(codec);
11517 alc268_acer_mic_automute(codec);
11520 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11521 /* output mixer control */
11522 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11523 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11524 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11525 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11526 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11527 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11531 static struct hda_verb alc268_dell_verbs[] = {
11532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11533 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11534 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11538 /* mute/unmute internal speaker according to the hp jack and mute state */
11539 static void alc268_dell_automute(struct hda_codec *codec)
11541 unsigned int present;
11544 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
11545 if (present & 0x80000000)
11546 mute = HDA_AMP_MUTE;
11548 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
11549 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11550 HDA_AMP_MUTE, mute);
11553 static void alc268_dell_unsol_event(struct hda_codec *codec,
11556 if ((res >> 26) != ALC880_HP_EVENT)
11558 alc268_dell_automute(codec);
11561 #define alc268_dell_init_hook alc268_dell_automute
11563 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11564 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11565 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11567 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11568 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11569 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11570 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11571 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11575 static struct hda_verb alc267_quanta_il1_verbs[] = {
11576 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11577 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11581 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11583 unsigned int present;
11585 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11586 & AC_PINSENSE_PRESENCE;
11587 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11588 present ? 0 : PIN_OUT);
11591 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11593 unsigned int present;
11595 present = snd_hda_codec_read(codec, 0x18, 0,
11596 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11597 snd_hda_codec_write(codec, 0x23, 0,
11598 AC_VERB_SET_CONNECT_SEL,
11599 present ? 0x00 : 0x01);
11602 static void alc267_quanta_il1_automute(struct hda_codec *codec)
11604 alc267_quanta_il1_hp_automute(codec);
11605 alc267_quanta_il1_mic_automute(codec);
11608 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11611 switch (res >> 26) {
11612 case ALC880_HP_EVENT:
11613 alc267_quanta_il1_hp_automute(codec);
11615 case ALC880_MIC_EVENT:
11616 alc267_quanta_il1_mic_automute(codec);
11622 * generic initialization of ADC, input mixers and output mixers
11624 static struct hda_verb alc268_base_init_verbs[] = {
11625 /* Unmute DAC0-1 and set vol = 0 */
11626 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11627 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11630 * Set up output mixers (0x0c - 0x0e)
11632 /* set vol=0 to output mixers */
11633 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11634 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11636 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11637 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11639 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11640 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11641 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11642 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11643 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11644 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11645 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11646 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11648 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11649 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11650 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11651 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11652 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11654 /* set PCBEEP vol = 0, mute connections */
11655 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11656 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11657 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11659 /* Unmute Selector 23h,24h and set the default input to mic-in */
11661 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11662 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11663 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11664 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11670 * generic initialization of ADC, input mixers and output mixers
11672 static struct hda_verb alc268_volume_init_verbs[] = {
11673 /* set output DAC */
11674 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11675 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11677 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11678 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11679 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11680 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11681 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11683 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11684 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11685 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11687 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11688 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11690 /* set PCBEEP vol = 0, mute connections */
11691 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11692 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11693 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11698 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11699 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11700 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11703 /* The multiple "Capture Source" controls confuse alsamixer
11704 * So call somewhat different..
11706 /* .name = "Capture Source", */
11707 .name = "Input Source",
11709 .info = alc_mux_enum_info,
11710 .get = alc_mux_enum_get,
11711 .put = alc_mux_enum_put,
11716 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11717 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11718 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11719 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11720 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11722 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11723 /* The multiple "Capture Source" controls confuse alsamixer
11724 * So call somewhat different..
11726 /* .name = "Capture Source", */
11727 .name = "Input Source",
11729 .info = alc_mux_enum_info,
11730 .get = alc_mux_enum_get,
11731 .put = alc_mux_enum_put,
11736 static struct hda_input_mux alc268_capture_source = {
11740 { "Front Mic", 0x1 },
11746 static struct hda_input_mux alc268_acer_capture_source = {
11750 { "Internal Mic", 0x1 },
11755 static struct hda_input_mux alc268_acer_dmic_capture_source = {
11759 { "Internal Mic", 0x6 },
11764 #ifdef CONFIG_SND_DEBUG
11765 static struct snd_kcontrol_new alc268_test_mixer[] = {
11766 /* Volume widgets */
11767 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11768 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11769 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11770 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11771 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11772 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11773 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11774 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11775 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11776 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11777 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11778 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11779 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11780 /* The below appears problematic on some hardwares */
11781 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11782 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11783 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11784 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11785 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11787 /* Modes for retasking pin widgets */
11788 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11789 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11790 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11791 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11793 /* Controls for GPIO pins, assuming they are configured as outputs */
11794 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11795 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11796 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11797 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11799 /* Switches to allow the digital SPDIF output pin to be enabled.
11800 * The ALC268 does not have an SPDIF input.
11802 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11804 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11805 * this output to turn on an external amplifier.
11807 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11808 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11814 /* create input playback/capture controls for the given pin */
11815 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11816 const char *ctlname, int idx)
11821 sprintf(name, "%s Playback Volume", ctlname);
11823 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11824 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11828 } else if (nid == 0x15) {
11829 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11830 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11836 sprintf(name, "%s Playback Switch", ctlname);
11837 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11838 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11844 /* add playback controls from the parsed DAC table */
11845 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11846 const struct auto_pin_cfg *cfg)
11851 spec->multiout.num_dacs = 2; /* only use one dac */
11852 spec->multiout.dac_nids = spec->private_dac_nids;
11853 spec->multiout.dac_nids[0] = 2;
11854 spec->multiout.dac_nids[1] = 3;
11856 nid = cfg->line_out_pins[0];
11858 alc268_new_analog_output(spec, nid, "Front", 0);
11860 nid = cfg->speaker_pins[0];
11862 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11863 "Speaker Playback Volume",
11864 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11868 nid = cfg->hp_pins[0];
11870 alc268_new_analog_output(spec, nid, "Headphone", 0);
11872 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11874 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11875 "Mono Playback Switch",
11876 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11883 /* create playback/capture controls for input pins */
11884 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11885 const struct auto_pin_cfg *cfg)
11887 struct hda_input_mux *imux = &spec->private_imux[0];
11890 for (i = 0; i < AUTO_PIN_LAST; i++) {
11891 switch(cfg->input_pins[i]) {
11893 idx1 = 0; /* Mic 1 */
11896 idx1 = 1; /* Mic 2 */
11899 idx1 = 2; /* Line In */
11906 idx1 = 6; /* digital mics */
11911 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11912 imux->items[imux->num_items].index = idx1;
11918 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11920 struct alc_spec *spec = codec->spec;
11921 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11922 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11923 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11924 unsigned int dac_vol1, dac_vol2;
11927 snd_hda_codec_write(codec, speaker_nid, 0,
11928 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11929 snd_hda_codec_write(codec, 0x0f, 0,
11930 AC_VERB_SET_AMP_GAIN_MUTE,
11932 snd_hda_codec_write(codec, 0x10, 0,
11933 AC_VERB_SET_AMP_GAIN_MUTE,
11936 snd_hda_codec_write(codec, 0x0f, 0,
11937 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11938 snd_hda_codec_write(codec, 0x10, 0,
11939 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11942 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11943 if (line_nid == 0x14)
11944 dac_vol2 = AMP_OUT_ZERO;
11945 else if (line_nid == 0x15)
11946 dac_vol1 = AMP_OUT_ZERO;
11947 if (hp_nid == 0x14)
11948 dac_vol2 = AMP_OUT_ZERO;
11949 else if (hp_nid == 0x15)
11950 dac_vol1 = AMP_OUT_ZERO;
11951 if (line_nid != 0x16 || hp_nid != 0x16 ||
11952 spec->autocfg.line_out_pins[1] != 0x16 ||
11953 spec->autocfg.line_out_pins[2] != 0x16)
11954 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11956 snd_hda_codec_write(codec, 0x02, 0,
11957 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11958 snd_hda_codec_write(codec, 0x03, 0,
11959 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11962 /* pcm configuration: identiacal with ALC880 */
11963 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11964 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11965 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11966 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11969 * BIOS auto configuration
11971 static int alc268_parse_auto_config(struct hda_codec *codec)
11973 struct alc_spec *spec = codec->spec;
11975 static hda_nid_t alc268_ignore[] = { 0 };
11977 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11981 if (!spec->autocfg.line_outs) {
11982 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11983 spec->multiout.max_channels = 2;
11984 spec->no_analog = 1;
11987 return 0; /* can't find valid BIOS pin config */
11989 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11992 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11996 spec->multiout.max_channels = 2;
11999 /* digital only support output */
12000 if (spec->autocfg.dig_outs) {
12001 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
12002 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12004 if (spec->kctls.list)
12005 add_mixer(spec, spec->kctls.list);
12007 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
12008 add_mixer(spec, alc268_beep_mixer);
12010 add_verb(spec, alc268_volume_init_verbs);
12011 spec->num_mux_defs = 1;
12012 spec->input_mux = &spec->private_imux[0];
12014 err = alc_auto_add_mic_boost(codec);
12021 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
12022 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
12023 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
12025 /* init callback for auto-configuration model -- overriding the default init */
12026 static void alc268_auto_init(struct hda_codec *codec)
12028 struct alc_spec *spec = codec->spec;
12029 alc268_auto_init_multi_out(codec);
12030 alc268_auto_init_hp_out(codec);
12031 alc268_auto_init_mono_speaker_out(codec);
12032 alc268_auto_init_analog_input(codec);
12033 if (spec->unsol_event)
12034 alc_inithook(codec);
12038 * configuration and preset
12040 static const char *alc268_models[ALC268_MODEL_LAST] = {
12041 [ALC267_QUANTA_IL1] = "quanta-il1",
12042 [ALC268_3ST] = "3stack",
12043 [ALC268_TOSHIBA] = "toshiba",
12044 [ALC268_ACER] = "acer",
12045 [ALC268_ACER_DMIC] = "acer-dmic",
12046 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
12047 [ALC268_DELL] = "dell",
12048 [ALC268_ZEPTO] = "zepto",
12049 #ifdef CONFIG_SND_DEBUG
12050 [ALC268_TEST] = "test",
12052 [ALC268_AUTO] = "auto",
12055 static struct snd_pci_quirk alc268_cfg_tbl[] = {
12056 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12057 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12058 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12059 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12060 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12061 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12062 ALC268_ACER_ASPIRE_ONE),
12063 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12064 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
12065 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
12066 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12067 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
12068 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
12069 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
12070 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12071 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12072 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12073 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12077 static struct alc_config_preset alc268_presets[] = {
12078 [ALC267_QUANTA_IL1] = {
12079 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
12080 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12081 alc267_quanta_il1_verbs },
12082 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12083 .dac_nids = alc268_dac_nids,
12084 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12085 .adc_nids = alc268_adc_nids_alt,
12087 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12088 .channel_mode = alc268_modes,
12089 .input_mux = &alc268_capture_source,
12090 .unsol_event = alc267_quanta_il1_unsol_event,
12091 .init_hook = alc267_quanta_il1_automute,
12094 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12095 alc268_beep_mixer },
12096 .init_verbs = { alc268_base_init_verbs },
12097 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12098 .dac_nids = alc268_dac_nids,
12099 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12100 .adc_nids = alc268_adc_nids_alt,
12101 .capsrc_nids = alc268_capsrc_nids,
12103 .dig_out_nid = ALC268_DIGOUT_NID,
12104 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12105 .channel_mode = alc268_modes,
12106 .input_mux = &alc268_capture_source,
12108 [ALC268_TOSHIBA] = {
12109 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12110 alc268_beep_mixer },
12111 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12112 alc268_toshiba_verbs },
12113 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12114 .dac_nids = alc268_dac_nids,
12115 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12116 .adc_nids = alc268_adc_nids_alt,
12117 .capsrc_nids = alc268_capsrc_nids,
12119 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12120 .channel_mode = alc268_modes,
12121 .input_mux = &alc268_capture_source,
12122 .unsol_event = alc268_toshiba_unsol_event,
12123 .init_hook = alc268_toshiba_automute,
12126 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12127 alc268_beep_mixer },
12128 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12129 alc268_acer_verbs },
12130 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12131 .dac_nids = alc268_dac_nids,
12132 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12133 .adc_nids = alc268_adc_nids_alt,
12134 .capsrc_nids = alc268_capsrc_nids,
12136 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12137 .channel_mode = alc268_modes,
12138 .input_mux = &alc268_acer_capture_source,
12139 .unsol_event = alc268_acer_unsol_event,
12140 .init_hook = alc268_acer_init_hook,
12142 [ALC268_ACER_DMIC] = {
12143 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12144 alc268_beep_mixer },
12145 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12146 alc268_acer_verbs },
12147 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12148 .dac_nids = alc268_dac_nids,
12149 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12150 .adc_nids = alc268_adc_nids_alt,
12151 .capsrc_nids = alc268_capsrc_nids,
12153 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12154 .channel_mode = alc268_modes,
12155 .input_mux = &alc268_acer_dmic_capture_source,
12156 .unsol_event = alc268_acer_unsol_event,
12157 .init_hook = alc268_acer_init_hook,
12159 [ALC268_ACER_ASPIRE_ONE] = {
12160 .mixers = { alc268_acer_aspire_one_mixer,
12162 alc268_capture_alt_mixer },
12163 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12164 alc268_acer_aspire_one_verbs },
12165 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12166 .dac_nids = alc268_dac_nids,
12167 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12168 .adc_nids = alc268_adc_nids_alt,
12169 .capsrc_nids = alc268_capsrc_nids,
12171 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12172 .channel_mode = alc268_modes,
12173 .input_mux = &alc268_acer_lc_capture_source,
12174 .unsol_event = alc268_acer_lc_unsol_event,
12175 .init_hook = alc268_acer_lc_init_hook,
12178 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
12179 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12180 alc268_dell_verbs },
12181 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12182 .dac_nids = alc268_dac_nids,
12184 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12185 .channel_mode = alc268_modes,
12186 .unsol_event = alc268_dell_unsol_event,
12187 .init_hook = alc268_dell_init_hook,
12188 .input_mux = &alc268_capture_source,
12191 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12192 alc268_beep_mixer },
12193 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12194 alc268_toshiba_verbs },
12195 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12196 .dac_nids = alc268_dac_nids,
12197 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12198 .adc_nids = alc268_adc_nids_alt,
12199 .capsrc_nids = alc268_capsrc_nids,
12201 .dig_out_nid = ALC268_DIGOUT_NID,
12202 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12203 .channel_mode = alc268_modes,
12204 .input_mux = &alc268_capture_source,
12205 .unsol_event = alc268_toshiba_unsol_event,
12206 .init_hook = alc268_toshiba_automute
12208 #ifdef CONFIG_SND_DEBUG
12210 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12211 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12212 alc268_volume_init_verbs },
12213 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12214 .dac_nids = alc268_dac_nids,
12215 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12216 .adc_nids = alc268_adc_nids_alt,
12217 .capsrc_nids = alc268_capsrc_nids,
12219 .dig_out_nid = ALC268_DIGOUT_NID,
12220 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12221 .channel_mode = alc268_modes,
12222 .input_mux = &alc268_capture_source,
12227 static int patch_alc268(struct hda_codec *codec)
12229 struct alc_spec *spec;
12231 int i, has_beep, err;
12233 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12237 codec->spec = spec;
12239 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12243 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12244 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
12245 "trying auto-probe from BIOS...\n");
12246 board_config = ALC268_AUTO;
12249 if (board_config == ALC268_AUTO) {
12250 /* automatic parse from the BIOS config */
12251 err = alc268_parse_auto_config(codec);
12257 "hda_codec: Cannot set up configuration "
12258 "from BIOS. Using base mode...\n");
12259 board_config = ALC268_3ST;
12263 if (board_config != ALC268_AUTO)
12264 setup_preset(spec, &alc268_presets[board_config]);
12266 if (codec->vendor_id == 0x10ec0267) {
12267 spec->stream_name_analog = "ALC267 Analog";
12268 spec->stream_name_digital = "ALC267 Digital";
12270 spec->stream_name_analog = "ALC268 Analog";
12271 spec->stream_name_digital = "ALC268 Digital";
12274 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12275 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12276 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12278 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12281 for (i = 0; i < spec->num_mixers; i++) {
12282 if (spec->mixers[i] == alc268_beep_mixer) {
12289 err = snd_hda_attach_beep_device(codec, 0x1);
12294 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12295 /* override the amp caps for beep generator */
12296 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12297 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12298 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12299 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12300 (0 << AC_AMPCAP_MUTE_SHIFT));
12303 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12304 /* check whether NID 0x07 is valid */
12305 unsigned int wcap = get_wcaps(codec, 0x07);
12309 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12310 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12311 spec->adc_nids = alc268_adc_nids_alt;
12312 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12313 add_mixer(spec, alc268_capture_alt_mixer);
12315 spec->adc_nids = alc268_adc_nids;
12316 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12317 add_mixer(spec, alc268_capture_mixer);
12319 spec->capsrc_nids = alc268_capsrc_nids;
12320 /* set default input source */
12321 for (i = 0; i < spec->num_adc_nids; i++)
12322 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12323 0, AC_VERB_SET_CONNECT_SEL,
12324 spec->input_mux->items[0].index);
12327 spec->vmaster_nid = 0x02;
12329 codec->patch_ops = alc_patch_ops;
12330 if (board_config == ALC268_AUTO)
12331 spec->init_hook = alc268_auto_init;
12333 codec->proc_widget_hook = print_realtek_coef;
12339 * ALC269 channel source setting (2 channel)
12341 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12343 #define alc269_dac_nids alc260_dac_nids
12345 static hda_nid_t alc269_adc_nids[1] = {
12350 static hda_nid_t alc269_capsrc_nids[1] = {
12354 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12358 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12366 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12374 #define alc269_modes alc260_modes
12375 #define alc269_capture_source alc880_lg_lw_capture_source
12377 static struct snd_kcontrol_new alc269_base_mixer[] = {
12378 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12379 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12380 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12381 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12382 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12383 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12384 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12385 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12386 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12387 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12388 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12389 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12393 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12394 /* output mixer control */
12395 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12397 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12398 .name = "Master Playback Switch",
12399 .info = snd_hda_mixer_amp_switch_info,
12400 .get = snd_hda_mixer_amp_switch_get,
12401 .put = alc268_acer_master_sw_put,
12402 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12406 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12407 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12408 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12409 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12413 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12414 /* output mixer control */
12415 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12417 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12418 .name = "Master Playback Switch",
12419 .info = snd_hda_mixer_amp_switch_info,
12420 .get = snd_hda_mixer_amp_switch_get,
12421 .put = alc268_acer_master_sw_put,
12422 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12424 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12425 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12426 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12427 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12428 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12429 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12430 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12431 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12432 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12436 /* bind volumes of both NID 0x0c and 0x0d */
12437 static struct hda_bind_ctls alc269_epc_bind_vol = {
12438 .ops = &snd_hda_bind_vol,
12440 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12441 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12446 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12447 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12448 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12449 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12453 /* capture mixer elements */
12454 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12455 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12456 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12457 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12462 static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12463 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12464 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12465 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
12469 static struct hda_verb alc269_quanta_fl1_verbs[] = {
12470 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12471 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12472 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12473 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12474 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12475 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12479 static struct hda_verb alc269_lifebook_verbs[] = {
12480 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12481 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12482 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12483 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12484 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12485 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12486 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12487 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12488 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12489 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12493 /* toggle speaker-output according to the hp-jack state */
12494 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12496 unsigned int present;
12497 unsigned char bits;
12499 present = snd_hda_codec_read(codec, 0x15, 0,
12500 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12501 bits = present ? AMP_IN_MUTE(0) : 0;
12502 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12503 AMP_IN_MUTE(0), bits);
12504 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12505 AMP_IN_MUTE(0), bits);
12507 snd_hda_codec_write(codec, 0x20, 0,
12508 AC_VERB_SET_COEF_INDEX, 0x0c);
12509 snd_hda_codec_write(codec, 0x20, 0,
12510 AC_VERB_SET_PROC_COEF, 0x680);
12512 snd_hda_codec_write(codec, 0x20, 0,
12513 AC_VERB_SET_COEF_INDEX, 0x0c);
12514 snd_hda_codec_write(codec, 0x20, 0,
12515 AC_VERB_SET_PROC_COEF, 0x480);
12518 /* toggle speaker-output according to the hp-jacks state */
12519 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12521 unsigned int present;
12522 unsigned char bits;
12524 /* Check laptop headphone socket */
12525 present = snd_hda_codec_read(codec, 0x15, 0,
12526 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12528 /* Check port replicator headphone socket */
12529 present |= snd_hda_codec_read(codec, 0x1a, 0,
12530 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12532 bits = present ? AMP_IN_MUTE(0) : 0;
12533 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12534 AMP_IN_MUTE(0), bits);
12535 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12536 AMP_IN_MUTE(0), bits);
12538 snd_hda_codec_write(codec, 0x20, 0,
12539 AC_VERB_SET_COEF_INDEX, 0x0c);
12540 snd_hda_codec_write(codec, 0x20, 0,
12541 AC_VERB_SET_PROC_COEF, 0x680);
12543 snd_hda_codec_write(codec, 0x20, 0,
12544 AC_VERB_SET_COEF_INDEX, 0x0c);
12545 snd_hda_codec_write(codec, 0x20, 0,
12546 AC_VERB_SET_PROC_COEF, 0x480);
12549 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12551 unsigned int present;
12553 present = snd_hda_codec_read(codec, 0x18, 0,
12554 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12555 snd_hda_codec_write(codec, 0x23, 0,
12556 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12559 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12561 unsigned int present_laptop;
12562 unsigned int present_dock;
12564 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12565 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12567 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12568 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12570 /* Laptop mic port overrides dock mic port, design decision */
12572 snd_hda_codec_write(codec, 0x23, 0,
12573 AC_VERB_SET_CONNECT_SEL, 0x3);
12574 if (present_laptop)
12575 snd_hda_codec_write(codec, 0x23, 0,
12576 AC_VERB_SET_CONNECT_SEL, 0x0);
12577 if (!present_dock && !present_laptop)
12578 snd_hda_codec_write(codec, 0x23, 0,
12579 AC_VERB_SET_CONNECT_SEL, 0x1);
12582 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12585 if ((res >> 26) == ALC880_HP_EVENT)
12586 alc269_quanta_fl1_speaker_automute(codec);
12587 if ((res >> 26) == ALC880_MIC_EVENT)
12588 alc269_quanta_fl1_mic_automute(codec);
12591 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12594 if ((res >> 26) == ALC880_HP_EVENT)
12595 alc269_lifebook_speaker_automute(codec);
12596 if ((res >> 26) == ALC880_MIC_EVENT)
12597 alc269_lifebook_mic_autoswitch(codec);
12600 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12602 alc269_quanta_fl1_speaker_automute(codec);
12603 alc269_quanta_fl1_mic_automute(codec);
12606 static void alc269_lifebook_init_hook(struct hda_codec *codec)
12608 alc269_lifebook_speaker_automute(codec);
12609 alc269_lifebook_mic_autoswitch(codec);
12612 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12613 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12614 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12615 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12616 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12617 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12618 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12619 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12623 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12624 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12625 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12626 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12627 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12628 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12629 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12633 /* toggle speaker-output according to the hp-jack state */
12634 static void alc269_speaker_automute(struct hda_codec *codec)
12636 unsigned int present;
12637 unsigned char bits;
12639 present = snd_hda_codec_read(codec, 0x15, 0,
12640 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12641 bits = present ? AMP_IN_MUTE(0) : 0;
12642 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12643 AMP_IN_MUTE(0), bits);
12644 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12645 AMP_IN_MUTE(0), bits);
12648 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12650 unsigned int present;
12652 present = snd_hda_codec_read(codec, 0x18, 0,
12653 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12654 snd_hda_codec_write(codec, 0x23, 0,
12655 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12658 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12660 unsigned int present;
12662 present = snd_hda_codec_read(codec, 0x18, 0,
12663 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12664 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12665 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12666 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12667 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12670 /* unsolicited event for HP jack sensing */
12671 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12674 if ((res >> 26) == ALC880_HP_EVENT)
12675 alc269_speaker_automute(codec);
12677 if ((res >> 26) == ALC880_MIC_EVENT)
12678 alc269_eeepc_dmic_automute(codec);
12681 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12683 alc269_speaker_automute(codec);
12684 alc269_eeepc_dmic_automute(codec);
12687 /* unsolicited event for HP jack sensing */
12688 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12691 if ((res >> 26) == ALC880_HP_EVENT)
12692 alc269_speaker_automute(codec);
12694 if ((res >> 26) == ALC880_MIC_EVENT)
12695 alc269_eeepc_amic_automute(codec);
12698 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12700 alc269_speaker_automute(codec);
12701 alc269_eeepc_amic_automute(codec);
12705 * generic initialization of ADC, input mixers and output mixers
12707 static struct hda_verb alc269_init_verbs[] = {
12709 * Unmute ADC0 and set the default input to mic-in
12711 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12713 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12714 * analog-loopback mixer widget
12715 * Note: PASD motherboards uses the Line In 2 as the input for
12716 * front panel mic (mic 2)
12718 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12719 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12720 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12721 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12726 * Set up output mixers (0x0c - 0x0e)
12728 /* set vol=0 to output mixers */
12729 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12730 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12732 /* set up input amps for analog loopback */
12733 /* Amp Indices: DAC = 0, mixer = 1 */
12734 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12735 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12736 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12737 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12738 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12739 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12741 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12742 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12743 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12744 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12745 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12746 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12747 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12750 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12751 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12752 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12753 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12754 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12755 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12757 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12758 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12760 /* FIXME: use matrix-type input source selection */
12761 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12762 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12763 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12764 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12765 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12766 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12769 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12770 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12774 /* add playback controls from the parsed DAC table */
12775 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12776 const struct auto_pin_cfg *cfg)
12781 spec->multiout.num_dacs = 1; /* only use one dac */
12782 spec->multiout.dac_nids = spec->private_dac_nids;
12783 spec->multiout.dac_nids[0] = 2;
12785 nid = cfg->line_out_pins[0];
12787 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12788 "Front Playback Volume",
12789 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12792 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12793 "Front Playback Switch",
12794 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12799 nid = cfg->speaker_pins[0];
12801 if (!cfg->line_out_pins[0]) {
12802 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12803 "Speaker Playback Volume",
12804 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12810 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12811 "Speaker Playback Switch",
12812 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12817 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12818 "Speaker Playback Switch",
12819 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12825 nid = cfg->hp_pins[0];
12827 /* spec->multiout.hp_nid = 2; */
12828 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12829 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12830 "Headphone Playback Volume",
12831 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12837 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12838 "Headphone Playback Switch",
12839 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12844 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12845 "Headphone Playback Switch",
12846 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12855 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12856 const struct auto_pin_cfg *cfg)
12860 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12863 /* digital-mic input pin is excluded in alc880_auto_create..()
12864 * because it's under 0x18
12866 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12867 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12868 struct hda_input_mux *imux = &spec->private_imux[0];
12869 imux->items[imux->num_items].label = "Int Mic";
12870 imux->items[imux->num_items].index = 0x05;
12876 #ifdef CONFIG_SND_HDA_POWER_SAVE
12877 #define alc269_loopbacks alc880_loopbacks
12880 /* pcm configuration: identiacal with ALC880 */
12881 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12882 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12883 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12884 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12886 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
12890 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12891 /* NID is set in alc_build_pcms */
12893 .open = alc880_playback_pcm_open,
12894 .prepare = alc880_playback_pcm_prepare,
12895 .cleanup = alc880_playback_pcm_cleanup
12899 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
12903 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12904 /* NID is set in alc_build_pcms */
12908 * BIOS auto configuration
12910 static int alc269_parse_auto_config(struct hda_codec *codec)
12912 struct alc_spec *spec = codec->spec;
12914 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12916 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12921 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12924 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12928 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12930 if (spec->autocfg.dig_outs)
12931 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12933 if (spec->kctls.list)
12934 add_mixer(spec, spec->kctls.list);
12936 add_verb(spec, alc269_init_verbs);
12937 spec->num_mux_defs = 1;
12938 spec->input_mux = &spec->private_imux[0];
12939 /* set default input source */
12940 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12941 0, AC_VERB_SET_CONNECT_SEL,
12942 spec->input_mux->items[0].index);
12944 err = alc_auto_add_mic_boost(codec);
12948 if (!spec->cap_mixer && !spec->no_analog)
12949 set_capture_mixer(spec);
12954 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12955 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12956 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12959 /* init callback for auto-configuration model -- overriding the default init */
12960 static void alc269_auto_init(struct hda_codec *codec)
12962 struct alc_spec *spec = codec->spec;
12963 alc269_auto_init_multi_out(codec);
12964 alc269_auto_init_hp_out(codec);
12965 alc269_auto_init_analog_input(codec);
12966 if (spec->unsol_event)
12967 alc_inithook(codec);
12971 * configuration and preset
12973 static const char *alc269_models[ALC269_MODEL_LAST] = {
12974 [ALC269_BASIC] = "basic",
12975 [ALC269_QUANTA_FL1] = "quanta",
12976 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12977 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
12978 [ALC269_FUJITSU] = "fujitsu",
12979 [ALC269_LIFEBOOK] = "lifebook"
12982 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12983 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12984 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12985 ALC269_ASUS_EEEPC_P703),
12986 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
12987 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
12988 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
12989 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
12990 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
12991 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
12992 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12993 ALC269_ASUS_EEEPC_P901),
12994 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12995 ALC269_ASUS_EEEPC_P901),
12996 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
12997 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12998 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13002 static struct alc_config_preset alc269_presets[] = {
13004 .mixers = { alc269_base_mixer },
13005 .init_verbs = { alc269_init_verbs },
13006 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13007 .dac_nids = alc269_dac_nids,
13009 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13010 .channel_mode = alc269_modes,
13011 .input_mux = &alc269_capture_source,
13013 [ALC269_QUANTA_FL1] = {
13014 .mixers = { alc269_quanta_fl1_mixer },
13015 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13016 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13017 .dac_nids = alc269_dac_nids,
13019 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13020 .channel_mode = alc269_modes,
13021 .input_mux = &alc269_capture_source,
13022 .unsol_event = alc269_quanta_fl1_unsol_event,
13023 .init_hook = alc269_quanta_fl1_init_hook,
13025 [ALC269_ASUS_EEEPC_P703] = {
13026 .mixers = { alc269_eeepc_mixer },
13027 .cap_mixer = alc269_epc_capture_mixer,
13028 .init_verbs = { alc269_init_verbs,
13029 alc269_eeepc_amic_init_verbs },
13030 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13031 .dac_nids = alc269_dac_nids,
13033 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13034 .channel_mode = alc269_modes,
13035 .input_mux = &alc269_eeepc_amic_capture_source,
13036 .unsol_event = alc269_eeepc_amic_unsol_event,
13037 .init_hook = alc269_eeepc_amic_inithook,
13039 [ALC269_ASUS_EEEPC_P901] = {
13040 .mixers = { alc269_eeepc_mixer },
13041 .cap_mixer = alc269_epc_capture_mixer,
13042 .init_verbs = { alc269_init_verbs,
13043 alc269_eeepc_dmic_init_verbs },
13044 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13045 .dac_nids = alc269_dac_nids,
13047 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13048 .channel_mode = alc269_modes,
13049 .input_mux = &alc269_eeepc_dmic_capture_source,
13050 .unsol_event = alc269_eeepc_dmic_unsol_event,
13051 .init_hook = alc269_eeepc_dmic_inithook,
13053 [ALC269_FUJITSU] = {
13054 .mixers = { alc269_fujitsu_mixer },
13055 .cap_mixer = alc269_epc_capture_mixer,
13056 .init_verbs = { alc269_init_verbs,
13057 alc269_eeepc_dmic_init_verbs },
13058 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13059 .dac_nids = alc269_dac_nids,
13061 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13062 .channel_mode = alc269_modes,
13063 .input_mux = &alc269_eeepc_dmic_capture_source,
13064 .unsol_event = alc269_eeepc_dmic_unsol_event,
13065 .init_hook = alc269_eeepc_dmic_inithook,
13067 [ALC269_LIFEBOOK] = {
13068 .mixers = { alc269_lifebook_mixer },
13069 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13070 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13071 .dac_nids = alc269_dac_nids,
13073 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13074 .channel_mode = alc269_modes,
13075 .input_mux = &alc269_capture_source,
13076 .unsol_event = alc269_lifebook_unsol_event,
13077 .init_hook = alc269_lifebook_init_hook,
13081 static int patch_alc269(struct hda_codec *codec)
13083 struct alc_spec *spec;
13087 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13091 codec->spec = spec;
13093 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13095 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13099 if (board_config < 0) {
13100 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
13101 "trying auto-probe from BIOS...\n");
13102 board_config = ALC269_AUTO;
13105 if (board_config == ALC269_AUTO) {
13106 /* automatic parse from the BIOS config */
13107 err = alc269_parse_auto_config(codec);
13113 "hda_codec: Cannot set up configuration "
13114 "from BIOS. Using base mode...\n");
13115 board_config = ALC269_BASIC;
13119 err = snd_hda_attach_beep_device(codec, 0x1);
13125 if (board_config != ALC269_AUTO)
13126 setup_preset(spec, &alc269_presets[board_config]);
13128 spec->stream_name_analog = "ALC269 Analog";
13129 if (codec->subsystem_id == 0x17aa3bf8) {
13130 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13131 * fix the sample rate of analog I/O to 44.1kHz
13133 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13134 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13136 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13137 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13139 spec->stream_name_digital = "ALC269 Digital";
13140 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13141 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13143 spec->adc_nids = alc269_adc_nids;
13144 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13145 spec->capsrc_nids = alc269_capsrc_nids;
13146 if (!spec->cap_mixer)
13147 set_capture_mixer(spec);
13148 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13150 codec->patch_ops = alc_patch_ops;
13151 if (board_config == ALC269_AUTO)
13152 spec->init_hook = alc269_auto_init;
13153 #ifdef CONFIG_SND_HDA_POWER_SAVE
13154 if (!spec->loopback.amplist)
13155 spec->loopback.amplist = alc269_loopbacks;
13157 codec->proc_widget_hook = print_realtek_coef;
13163 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13167 * set the path ways for 2 channel output
13168 * need to set the codec line out and mic 1 pin widgets to inputs
13170 static struct hda_verb alc861_threestack_ch2_init[] = {
13171 /* set pin widget 1Ah (line in) for input */
13172 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13173 /* set pin widget 18h (mic1/2) for input, for mic also enable
13176 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13178 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13180 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13181 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13187 * need to set the codec line out and mic 1 pin widgets to outputs
13189 static struct hda_verb alc861_threestack_ch6_init[] = {
13190 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13191 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13192 /* set pin widget 18h (mic1) for output (CLFE)*/
13193 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13195 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13196 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13198 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13200 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13201 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13206 static struct hda_channel_mode alc861_threestack_modes[2] = {
13207 { 2, alc861_threestack_ch2_init },
13208 { 6, alc861_threestack_ch6_init },
13210 /* Set mic1 as input and unmute the mixer */
13211 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13212 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13213 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13216 /* Set mic1 as output and mute mixer */
13217 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13218 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13219 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13223 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13224 { 2, alc861_uniwill_m31_ch2_init },
13225 { 4, alc861_uniwill_m31_ch4_init },
13228 /* Set mic1 and line-in as input and unmute the mixer */
13229 static struct hda_verb alc861_asus_ch2_init[] = {
13230 /* set pin widget 1Ah (line in) for input */
13231 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13232 /* set pin widget 18h (mic1/2) for input, for mic also enable
13235 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13237 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13239 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13240 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13244 /* Set mic1 nad line-in as output and mute mixer */
13245 static struct hda_verb alc861_asus_ch6_init[] = {
13246 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13247 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13248 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13249 /* set pin widget 18h (mic1) for output (CLFE)*/
13250 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13251 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13252 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13253 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13255 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13257 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13258 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13263 static struct hda_channel_mode alc861_asus_modes[2] = {
13264 { 2, alc861_asus_ch2_init },
13265 { 6, alc861_asus_ch6_init },
13270 static struct snd_kcontrol_new alc861_base_mixer[] = {
13271 /* output mixer control */
13272 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13273 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13274 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13275 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13276 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13278 /*Input mixer control */
13279 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13280 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13281 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13282 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13283 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13284 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13285 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13286 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13287 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13288 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13293 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13294 /* output mixer control */
13295 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13296 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13297 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13298 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13299 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13301 /* Input mixer control */
13302 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13303 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13304 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13305 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13306 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13307 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13308 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13309 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13310 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13311 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13314 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13315 .name = "Channel Mode",
13316 .info = alc_ch_mode_info,
13317 .get = alc_ch_mode_get,
13318 .put = alc_ch_mode_put,
13319 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13324 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13325 /* output mixer control */
13326 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13327 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13328 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13333 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13334 /* output mixer control */
13335 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13336 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13337 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13338 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13339 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13341 /* Input mixer control */
13342 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13343 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13344 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13345 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13346 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13347 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13348 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13349 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13350 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13351 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13354 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13355 .name = "Channel Mode",
13356 .info = alc_ch_mode_info,
13357 .get = alc_ch_mode_get,
13358 .put = alc_ch_mode_put,
13359 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13364 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13365 /* output mixer control */
13366 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13367 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13368 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13369 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13370 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13372 /* Input mixer control */
13373 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13374 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13375 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13376 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13377 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13378 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13379 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13380 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13381 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13386 .name = "Channel Mode",
13387 .info = alc_ch_mode_info,
13388 .get = alc_ch_mode_get,
13389 .put = alc_ch_mode_put,
13390 .private_value = ARRAY_SIZE(alc861_asus_modes),
13395 /* additional mixer */
13396 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13397 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13398 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13403 * generic initialization of ADC, input mixers and output mixers
13405 static struct hda_verb alc861_base_init_verbs[] = {
13407 * Unmute ADC0 and set the default input to mic-in
13409 /* port-A for surround (rear panel) */
13410 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13411 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13412 /* port-B for mic-in (rear panel) with vref */
13413 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13414 /* port-C for line-in (rear panel) */
13415 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13416 /* port-D for Front */
13417 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13418 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13419 /* port-E for HP out (front panel) */
13420 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13421 /* route front PCM to HP */
13422 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13423 /* port-F for mic-in (front panel) with vref */
13424 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13425 /* port-G for CLFE (rear panel) */
13426 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13427 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13428 /* port-H for side (rear panel) */
13429 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13430 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13432 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13433 /* route front mic to ADC1*/
13434 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13435 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13437 /* Unmute DAC0~3 & spdif out*/
13438 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13439 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13440 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13441 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13442 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13444 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13445 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13446 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13447 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13448 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13450 /* Unmute Stereo Mixer 15 */
13451 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13452 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13453 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13456 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13457 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13458 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13459 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13460 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13461 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13462 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13463 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13464 /* hp used DAC 3 (Front) */
13465 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13466 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13471 static struct hda_verb alc861_threestack_init_verbs[] = {
13473 * Unmute ADC0 and set the default input to mic-in
13475 /* port-A for surround (rear panel) */
13476 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13477 /* port-B for mic-in (rear panel) with vref */
13478 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13479 /* port-C for line-in (rear panel) */
13480 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13481 /* port-D for Front */
13482 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13483 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13484 /* port-E for HP out (front panel) */
13485 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13486 /* route front PCM to HP */
13487 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13488 /* port-F for mic-in (front panel) with vref */
13489 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13490 /* port-G for CLFE (rear panel) */
13491 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13492 /* port-H for side (rear panel) */
13493 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13495 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13496 /* route front mic to ADC1*/
13497 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13498 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13499 /* Unmute DAC0~3 & spdif out*/
13500 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13501 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13502 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13503 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13504 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13506 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13507 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13508 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13509 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13510 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13512 /* Unmute Stereo Mixer 15 */
13513 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13514 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13515 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13516 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13518 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13519 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13520 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13521 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13522 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13523 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13524 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13525 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13526 /* hp used DAC 3 (Front) */
13527 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13528 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13532 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13534 * Unmute ADC0 and set the default input to mic-in
13536 /* port-A for surround (rear panel) */
13537 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13538 /* port-B for mic-in (rear panel) with vref */
13539 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13540 /* port-C for line-in (rear panel) */
13541 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13542 /* port-D for Front */
13543 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13544 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13545 /* port-E for HP out (front panel) */
13546 /* this has to be set to VREF80 */
13547 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13548 /* route front PCM to HP */
13549 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13550 /* port-F for mic-in (front panel) with vref */
13551 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13552 /* port-G for CLFE (rear panel) */
13553 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13554 /* port-H for side (rear panel) */
13555 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13557 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13558 /* route front mic to ADC1*/
13559 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13560 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13561 /* Unmute DAC0~3 & spdif out*/
13562 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13563 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13564 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13565 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13568 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13569 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13570 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13571 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13572 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13574 /* Unmute Stereo Mixer 15 */
13575 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13576 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13578 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13580 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13581 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13582 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13583 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13584 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13585 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13586 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13587 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13588 /* hp used DAC 3 (Front) */
13589 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13590 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13594 static struct hda_verb alc861_asus_init_verbs[] = {
13596 * Unmute ADC0 and set the default input to mic-in
13598 /* port-A for surround (rear panel)
13599 * according to codec#0 this is the HP jack
13601 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13602 /* route front PCM to HP */
13603 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13604 /* port-B for mic-in (rear panel) with vref */
13605 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13606 /* port-C for line-in (rear panel) */
13607 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13608 /* port-D for Front */
13609 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13610 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13611 /* port-E for HP out (front panel) */
13612 /* this has to be set to VREF80 */
13613 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13614 /* route front PCM to HP */
13615 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13616 /* port-F for mic-in (front panel) with vref */
13617 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13618 /* port-G for CLFE (rear panel) */
13619 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13620 /* port-H for side (rear panel) */
13621 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13623 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13624 /* route front mic to ADC1*/
13625 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13626 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13627 /* Unmute DAC0~3 & spdif out*/
13628 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13629 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13630 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13631 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13632 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13633 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13634 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13635 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13636 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13637 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13639 /* Unmute Stereo Mixer 15 */
13640 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13641 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13642 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13645 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13646 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13647 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13648 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13649 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13650 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13651 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13652 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13653 /* hp used DAC 3 (Front) */
13654 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13655 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13659 /* additional init verbs for ASUS laptops */
13660 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13661 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13662 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13667 * generic initialization of ADC, input mixers and output mixers
13669 static struct hda_verb alc861_auto_init_verbs[] = {
13671 * Unmute ADC0 and set the default input to mic-in
13673 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13674 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13676 /* Unmute DAC0~3 & spdif out*/
13677 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13678 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13679 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13680 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13683 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13684 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13685 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13686 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13687 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13689 /* Unmute Stereo Mixer 15 */
13690 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13691 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13692 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13695 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13696 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13697 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13698 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13699 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13700 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13701 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13702 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13704 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13705 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13706 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13707 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13708 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13709 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13710 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13711 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13713 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13718 static struct hda_verb alc861_toshiba_init_verbs[] = {
13719 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13724 /* toggle speaker-output according to the hp-jack state */
13725 static void alc861_toshiba_automute(struct hda_codec *codec)
13727 unsigned int present;
13729 present = snd_hda_codec_read(codec, 0x0f, 0,
13730 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13731 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13732 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13733 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13734 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13737 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13740 if ((res >> 26) == ALC880_HP_EVENT)
13741 alc861_toshiba_automute(codec);
13744 /* pcm configuration: identiacal with ALC880 */
13745 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13746 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13747 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13748 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13751 #define ALC861_DIGOUT_NID 0x07
13753 static struct hda_channel_mode alc861_8ch_modes[1] = {
13757 static hda_nid_t alc861_dac_nids[4] = {
13758 /* front, surround, clfe, side */
13759 0x03, 0x06, 0x05, 0x04
13762 static hda_nid_t alc660_dac_nids[3] = {
13763 /* front, clfe, surround */
13767 static hda_nid_t alc861_adc_nids[1] = {
13772 static struct hda_input_mux alc861_capture_source = {
13776 { "Front Mic", 0x3 },
13783 /* fill in the dac_nids table from the parsed pin configuration */
13784 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13785 const struct auto_pin_cfg *cfg)
13790 spec->multiout.dac_nids = spec->private_dac_nids;
13791 for (i = 0; i < cfg->line_outs; i++) {
13792 nid = cfg->line_out_pins[i];
13794 if (i >= ARRAY_SIZE(alc861_dac_nids))
13796 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13799 spec->multiout.num_dacs = cfg->line_outs;
13803 /* add playback controls from the parsed DAC table */
13804 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13805 const struct auto_pin_cfg *cfg)
13808 static const char *chname[4] = {
13809 "Front", "Surround", NULL /*CLFE*/, "Side"
13814 for (i = 0; i < cfg->line_outs; i++) {
13815 nid = spec->multiout.dac_nids[i];
13820 err = add_control(spec, ALC_CTL_BIND_MUTE,
13821 "Center Playback Switch",
13822 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13826 err = add_control(spec, ALC_CTL_BIND_MUTE,
13827 "LFE Playback Switch",
13828 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13833 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13835 if (nid == alc861_dac_nids[idx])
13837 sprintf(name, "%s Playback Switch", chname[idx]);
13838 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13839 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13848 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13856 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13858 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13859 "Headphone Playback Switch",
13860 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13863 spec->multiout.hp_nid = nid;
13868 /* create playback/capture controls for input pins */
13869 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13870 const struct auto_pin_cfg *cfg)
13872 struct hda_input_mux *imux = &spec->private_imux[0];
13873 int i, err, idx, idx1;
13875 for (i = 0; i < AUTO_PIN_LAST; i++) {
13876 switch (cfg->input_pins[i]) {
13879 idx = 2; /* Line In */
13883 idx = 2; /* Line In */
13887 idx = 1; /* Mic In */
13891 idx = 1; /* Mic In */
13901 err = new_analog_input(spec, cfg->input_pins[i],
13902 auto_pin_cfg_labels[i], idx, 0x15);
13906 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13907 imux->items[imux->num_items].index = idx1;
13913 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13915 int pin_type, int dac_idx)
13917 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13919 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13923 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13925 struct alc_spec *spec = codec->spec;
13928 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13929 for (i = 0; i < spec->autocfg.line_outs; i++) {
13930 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13931 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13933 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13934 spec->multiout.dac_nids[i]);
13938 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13940 struct alc_spec *spec = codec->spec;
13943 pin = spec->autocfg.hp_pins[0];
13944 if (pin) /* connect to front */
13945 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13946 spec->multiout.dac_nids[0]);
13947 pin = spec->autocfg.speaker_pins[0];
13949 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13952 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13954 struct alc_spec *spec = codec->spec;
13957 for (i = 0; i < AUTO_PIN_LAST; i++) {
13958 hda_nid_t nid = spec->autocfg.input_pins[i];
13959 if (nid >= 0x0c && nid <= 0x11)
13960 alc_set_input_pin(codec, nid, i);
13964 /* parse the BIOS configuration and set up the alc_spec */
13965 /* return 1 if successful, 0 if the proper config is not found,
13966 * or a negative error code
13968 static int alc861_parse_auto_config(struct hda_codec *codec)
13970 struct alc_spec *spec = codec->spec;
13972 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13974 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13978 if (!spec->autocfg.line_outs)
13979 return 0; /* can't find valid BIOS pin config */
13981 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13984 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13987 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13990 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13994 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13996 if (spec->autocfg.dig_outs)
13997 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13999 if (spec->kctls.list)
14000 add_mixer(spec, spec->kctls.list);
14002 add_verb(spec, alc861_auto_init_verbs);
14004 spec->num_mux_defs = 1;
14005 spec->input_mux = &spec->private_imux[0];
14007 spec->adc_nids = alc861_adc_nids;
14008 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14009 set_capture_mixer(spec);
14014 /* additional initialization for auto-configuration model */
14015 static void alc861_auto_init(struct hda_codec *codec)
14017 struct alc_spec *spec = codec->spec;
14018 alc861_auto_init_multi_out(codec);
14019 alc861_auto_init_hp_out(codec);
14020 alc861_auto_init_analog_input(codec);
14021 if (spec->unsol_event)
14022 alc_inithook(codec);
14025 #ifdef CONFIG_SND_HDA_POWER_SAVE
14026 static struct hda_amp_list alc861_loopbacks[] = {
14027 { 0x15, HDA_INPUT, 0 },
14028 { 0x15, HDA_INPUT, 1 },
14029 { 0x15, HDA_INPUT, 2 },
14030 { 0x15, HDA_INPUT, 3 },
14037 * configuration and preset
14039 static const char *alc861_models[ALC861_MODEL_LAST] = {
14040 [ALC861_3ST] = "3stack",
14041 [ALC660_3ST] = "3stack-660",
14042 [ALC861_3ST_DIG] = "3stack-dig",
14043 [ALC861_6ST_DIG] = "6stack-dig",
14044 [ALC861_UNIWILL_M31] = "uniwill-m31",
14045 [ALC861_TOSHIBA] = "toshiba",
14046 [ALC861_ASUS] = "asus",
14047 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14048 [ALC861_AUTO] = "auto",
14051 static struct snd_pci_quirk alc861_cfg_tbl[] = {
14052 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14053 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14054 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14055 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14056 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14057 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14058 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14059 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14060 * Any other models that need this preset?
14062 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14063 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14064 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14065 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14066 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14067 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14068 /* FIXME: the below seems conflict */
14069 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14070 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14071 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14075 static struct alc_config_preset alc861_presets[] = {
14077 .mixers = { alc861_3ST_mixer },
14078 .init_verbs = { alc861_threestack_init_verbs },
14079 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14080 .dac_nids = alc861_dac_nids,
14081 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14082 .channel_mode = alc861_threestack_modes,
14084 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14085 .adc_nids = alc861_adc_nids,
14086 .input_mux = &alc861_capture_source,
14088 [ALC861_3ST_DIG] = {
14089 .mixers = { alc861_base_mixer },
14090 .init_verbs = { alc861_threestack_init_verbs },
14091 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14092 .dac_nids = alc861_dac_nids,
14093 .dig_out_nid = ALC861_DIGOUT_NID,
14094 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14095 .channel_mode = alc861_threestack_modes,
14097 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14098 .adc_nids = alc861_adc_nids,
14099 .input_mux = &alc861_capture_source,
14101 [ALC861_6ST_DIG] = {
14102 .mixers = { alc861_base_mixer },
14103 .init_verbs = { alc861_base_init_verbs },
14104 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14105 .dac_nids = alc861_dac_nids,
14106 .dig_out_nid = ALC861_DIGOUT_NID,
14107 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14108 .channel_mode = alc861_8ch_modes,
14109 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14110 .adc_nids = alc861_adc_nids,
14111 .input_mux = &alc861_capture_source,
14114 .mixers = { alc861_3ST_mixer },
14115 .init_verbs = { alc861_threestack_init_verbs },
14116 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14117 .dac_nids = alc660_dac_nids,
14118 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14119 .channel_mode = alc861_threestack_modes,
14121 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14122 .adc_nids = alc861_adc_nids,
14123 .input_mux = &alc861_capture_source,
14125 [ALC861_UNIWILL_M31] = {
14126 .mixers = { alc861_uniwill_m31_mixer },
14127 .init_verbs = { alc861_uniwill_m31_init_verbs },
14128 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14129 .dac_nids = alc861_dac_nids,
14130 .dig_out_nid = ALC861_DIGOUT_NID,
14131 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14132 .channel_mode = alc861_uniwill_m31_modes,
14134 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14135 .adc_nids = alc861_adc_nids,
14136 .input_mux = &alc861_capture_source,
14138 [ALC861_TOSHIBA] = {
14139 .mixers = { alc861_toshiba_mixer },
14140 .init_verbs = { alc861_base_init_verbs,
14141 alc861_toshiba_init_verbs },
14142 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14143 .dac_nids = alc861_dac_nids,
14144 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14145 .channel_mode = alc883_3ST_2ch_modes,
14146 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14147 .adc_nids = alc861_adc_nids,
14148 .input_mux = &alc861_capture_source,
14149 .unsol_event = alc861_toshiba_unsol_event,
14150 .init_hook = alc861_toshiba_automute,
14153 .mixers = { alc861_asus_mixer },
14154 .init_verbs = { alc861_asus_init_verbs },
14155 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14156 .dac_nids = alc861_dac_nids,
14157 .dig_out_nid = ALC861_DIGOUT_NID,
14158 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14159 .channel_mode = alc861_asus_modes,
14162 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14163 .adc_nids = alc861_adc_nids,
14164 .input_mux = &alc861_capture_source,
14166 [ALC861_ASUS_LAPTOP] = {
14167 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14168 .init_verbs = { alc861_asus_init_verbs,
14169 alc861_asus_laptop_init_verbs },
14170 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14171 .dac_nids = alc861_dac_nids,
14172 .dig_out_nid = ALC861_DIGOUT_NID,
14173 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14174 .channel_mode = alc883_3ST_2ch_modes,
14176 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14177 .adc_nids = alc861_adc_nids,
14178 .input_mux = &alc861_capture_source,
14183 static int patch_alc861(struct hda_codec *codec)
14185 struct alc_spec *spec;
14189 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14193 codec->spec = spec;
14195 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14199 if (board_config < 0) {
14200 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
14201 "trying auto-probe from BIOS...\n");
14202 board_config = ALC861_AUTO;
14205 if (board_config == ALC861_AUTO) {
14206 /* automatic parse from the BIOS config */
14207 err = alc861_parse_auto_config(codec);
14213 "hda_codec: Cannot set up configuration "
14214 "from BIOS. Using base mode...\n");
14215 board_config = ALC861_3ST_DIG;
14219 err = snd_hda_attach_beep_device(codec, 0x23);
14225 if (board_config != ALC861_AUTO)
14226 setup_preset(spec, &alc861_presets[board_config]);
14228 spec->stream_name_analog = "ALC861 Analog";
14229 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14230 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14232 spec->stream_name_digital = "ALC861 Digital";
14233 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14234 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14236 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14238 spec->vmaster_nid = 0x03;
14240 codec->patch_ops = alc_patch_ops;
14241 if (board_config == ALC861_AUTO)
14242 spec->init_hook = alc861_auto_init;
14243 #ifdef CONFIG_SND_HDA_POWER_SAVE
14244 if (!spec->loopback.amplist)
14245 spec->loopback.amplist = alc861_loopbacks;
14247 codec->proc_widget_hook = print_realtek_coef;
14253 * ALC861-VD support
14257 * In addition, an independent DAC
14259 #define ALC861VD_DIGOUT_NID 0x06
14261 static hda_nid_t alc861vd_dac_nids[4] = {
14262 /* front, surr, clfe, side surr */
14263 0x02, 0x03, 0x04, 0x05
14266 /* dac_nids for ALC660vd are in a different order - according to
14267 * Realtek's driver.
14268 * This should probably tesult in a different mixer for 6stack models
14269 * of ALC660vd codecs, but for now there is only 3stack mixer
14270 * - and it is the same as in 861vd.
14271 * adc_nids in ALC660vd are (is) the same as in 861vd
14273 static hda_nid_t alc660vd_dac_nids[3] = {
14274 /* front, rear, clfe, rear_surr */
14278 static hda_nid_t alc861vd_adc_nids[1] = {
14283 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14286 /* FIXME: should be a matrix-type input source selection */
14287 static struct hda_input_mux alc861vd_capture_source = {
14291 { "Front Mic", 0x1 },
14297 static struct hda_input_mux alc861vd_dallas_capture_source = {
14300 { "Ext Mic", 0x0 },
14301 { "Int Mic", 0x1 },
14305 static struct hda_input_mux alc861vd_hp_capture_source = {
14308 { "Front Mic", 0x0 },
14309 { "ATAPI Mic", 0x1 },
14316 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14323 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14324 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14325 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14326 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14327 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14334 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14335 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14336 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14337 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14338 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14342 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14343 { 6, alc861vd_6stack_ch6_init },
14344 { 8, alc861vd_6stack_ch8_init },
14347 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14349 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14350 .name = "Channel Mode",
14351 .info = alc_ch_mode_info,
14352 .get = alc_ch_mode_get,
14353 .put = alc_ch_mode_put,
14358 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14359 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14361 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14362 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14363 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14365 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14366 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14368 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14370 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14372 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14373 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14375 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14376 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14378 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14380 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14381 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14382 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14384 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14385 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14386 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14388 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14389 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14391 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14392 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14397 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14398 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14399 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14401 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14403 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14407 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14408 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14409 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14411 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14412 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14414 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14415 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14420 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14421 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14422 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14423 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14425 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14427 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14428 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14429 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14431 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14432 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14433 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14435 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14436 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14441 /* Pin assignment: Speaker=0x14, HP = 0x15,
14442 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14444 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14445 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14446 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14447 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14448 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14449 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14450 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14451 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14452 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14453 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14454 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14458 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14459 * Front Mic=0x18, ATAPI Mic = 0x19,
14461 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14462 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14463 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14464 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14465 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14466 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14467 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14468 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14469 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14475 * generic initialization of ADC, input mixers and output mixers
14477 static struct hda_verb alc861vd_volume_init_verbs[] = {
14479 * Unmute ADC0 and set the default input to mic-in
14481 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14482 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14484 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14485 * the analog-loopback mixer widget
14487 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14488 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14489 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14490 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14491 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14492 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14494 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14495 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14496 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14497 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14498 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14501 * Set up output mixers (0x02 - 0x05)
14503 /* set vol=0 to output mixers */
14504 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14505 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14506 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14507 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14509 /* set up input amps for analog loopback */
14510 /* Amp Indices: DAC = 0, mixer = 1 */
14511 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14515 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14517 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14518 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14524 * 3-stack pin configuration:
14525 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14527 static struct hda_verb alc861vd_3stack_init_verbs[] = {
14529 * Set pin mode and muting
14531 /* set front pin widgets 0x14 for output */
14532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14534 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14536 /* Mic (rear) pin: input vref at 80% */
14537 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14538 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14539 /* Front Mic pin: input vref at 80% */
14540 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14541 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14542 /* Line In pin: input */
14543 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14544 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14545 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14546 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14547 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14548 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14549 /* CD pin widget for input */
14550 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14556 * 6-stack pin configuration:
14558 static struct hda_verb alc861vd_6stack_init_verbs[] = {
14560 * Set pin mode and muting
14562 /* set front pin widgets 0x14 for output */
14563 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14564 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14565 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14567 /* Rear Pin: output 1 (0x0d) */
14568 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14569 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14570 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14571 /* CLFE Pin: output 2 (0x0e) */
14572 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14573 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14574 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14575 /* Side Pin: output 3 (0x0f) */
14576 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14577 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14578 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14580 /* Mic (rear) pin: input vref at 80% */
14581 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14582 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14583 /* Front Mic pin: input vref at 80% */
14584 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14585 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14586 /* Line In pin: input */
14587 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14588 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14589 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14590 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14591 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14592 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14593 /* CD pin widget for input */
14594 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14599 static struct hda_verb alc861vd_eapd_verbs[] = {
14600 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14604 static struct hda_verb alc660vd_eapd_verbs[] = {
14605 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14606 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14610 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14613 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14614 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14615 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14619 /* toggle speaker-output according to the hp-jack state */
14620 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
14622 unsigned int present;
14623 unsigned char bits;
14625 present = snd_hda_codec_read(codec, 0x1b, 0,
14626 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14627 bits = present ? HDA_AMP_MUTE : 0;
14628 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14629 HDA_AMP_MUTE, bits);
14632 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14634 unsigned int present;
14635 unsigned char bits;
14637 present = snd_hda_codec_read(codec, 0x18, 0,
14638 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14639 bits = present ? HDA_AMP_MUTE : 0;
14640 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14641 HDA_AMP_MUTE, bits);
14644 static void alc861vd_lenovo_automute(struct hda_codec *codec)
14646 alc861vd_lenovo_hp_automute(codec);
14647 alc861vd_lenovo_mic_automute(codec);
14650 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14653 switch (res >> 26) {
14654 case ALC880_HP_EVENT:
14655 alc861vd_lenovo_hp_automute(codec);
14657 case ALC880_MIC_EVENT:
14658 alc861vd_lenovo_mic_automute(codec);
14663 static struct hda_verb alc861vd_dallas_verbs[] = {
14664 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14665 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14666 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14667 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14669 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14670 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14671 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14672 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14673 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14674 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14675 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14676 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14679 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14681 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14682 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14683 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14684 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14685 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14687 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14688 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14689 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14690 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14691 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14692 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14693 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14694 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14696 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14697 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14698 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14699 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14701 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14702 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14703 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14708 /* toggle speaker-output according to the hp-jack state */
14709 static void alc861vd_dallas_automute(struct hda_codec *codec)
14711 unsigned int present;
14713 present = snd_hda_codec_read(codec, 0x15, 0,
14714 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14715 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14716 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14719 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14721 if ((res >> 26) == ALC880_HP_EVENT)
14722 alc861vd_dallas_automute(codec);
14725 #ifdef CONFIG_SND_HDA_POWER_SAVE
14726 #define alc861vd_loopbacks alc880_loopbacks
14729 /* pcm configuration: identiacal with ALC880 */
14730 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14731 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14732 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14733 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14736 * configuration and preset
14738 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14739 [ALC660VD_3ST] = "3stack-660",
14740 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14741 [ALC660VD_ASUS_V1S] = "asus-v1s",
14742 [ALC861VD_3ST] = "3stack",
14743 [ALC861VD_3ST_DIG] = "3stack-digout",
14744 [ALC861VD_6ST_DIG] = "6stack-digout",
14745 [ALC861VD_LENOVO] = "lenovo",
14746 [ALC861VD_DALLAS] = "dallas",
14747 [ALC861VD_HP] = "hp",
14748 [ALC861VD_AUTO] = "auto",
14751 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14752 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14753 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14754 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14755 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14756 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14757 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14758 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14759 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14760 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14761 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14762 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14763 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14764 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14765 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
14766 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14770 static struct alc_config_preset alc861vd_presets[] = {
14772 .mixers = { alc861vd_3st_mixer },
14773 .init_verbs = { alc861vd_volume_init_verbs,
14774 alc861vd_3stack_init_verbs },
14775 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14776 .dac_nids = alc660vd_dac_nids,
14777 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14778 .channel_mode = alc861vd_3stack_2ch_modes,
14779 .input_mux = &alc861vd_capture_source,
14781 [ALC660VD_3ST_DIG] = {
14782 .mixers = { alc861vd_3st_mixer },
14783 .init_verbs = { alc861vd_volume_init_verbs,
14784 alc861vd_3stack_init_verbs },
14785 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14786 .dac_nids = alc660vd_dac_nids,
14787 .dig_out_nid = ALC861VD_DIGOUT_NID,
14788 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14789 .channel_mode = alc861vd_3stack_2ch_modes,
14790 .input_mux = &alc861vd_capture_source,
14793 .mixers = { alc861vd_3st_mixer },
14794 .init_verbs = { alc861vd_volume_init_verbs,
14795 alc861vd_3stack_init_verbs },
14796 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14797 .dac_nids = alc861vd_dac_nids,
14798 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14799 .channel_mode = alc861vd_3stack_2ch_modes,
14800 .input_mux = &alc861vd_capture_source,
14802 [ALC861VD_3ST_DIG] = {
14803 .mixers = { alc861vd_3st_mixer },
14804 .init_verbs = { alc861vd_volume_init_verbs,
14805 alc861vd_3stack_init_verbs },
14806 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14807 .dac_nids = alc861vd_dac_nids,
14808 .dig_out_nid = ALC861VD_DIGOUT_NID,
14809 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14810 .channel_mode = alc861vd_3stack_2ch_modes,
14811 .input_mux = &alc861vd_capture_source,
14813 [ALC861VD_6ST_DIG] = {
14814 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14815 .init_verbs = { alc861vd_volume_init_verbs,
14816 alc861vd_6stack_init_verbs },
14817 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14818 .dac_nids = alc861vd_dac_nids,
14819 .dig_out_nid = ALC861VD_DIGOUT_NID,
14820 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14821 .channel_mode = alc861vd_6stack_modes,
14822 .input_mux = &alc861vd_capture_source,
14824 [ALC861VD_LENOVO] = {
14825 .mixers = { alc861vd_lenovo_mixer },
14826 .init_verbs = { alc861vd_volume_init_verbs,
14827 alc861vd_3stack_init_verbs,
14828 alc861vd_eapd_verbs,
14829 alc861vd_lenovo_unsol_verbs },
14830 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14831 .dac_nids = alc660vd_dac_nids,
14832 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14833 .channel_mode = alc861vd_3stack_2ch_modes,
14834 .input_mux = &alc861vd_capture_source,
14835 .unsol_event = alc861vd_lenovo_unsol_event,
14836 .init_hook = alc861vd_lenovo_automute,
14838 [ALC861VD_DALLAS] = {
14839 .mixers = { alc861vd_dallas_mixer },
14840 .init_verbs = { alc861vd_dallas_verbs },
14841 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14842 .dac_nids = alc861vd_dac_nids,
14843 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14844 .channel_mode = alc861vd_3stack_2ch_modes,
14845 .input_mux = &alc861vd_dallas_capture_source,
14846 .unsol_event = alc861vd_dallas_unsol_event,
14847 .init_hook = alc861vd_dallas_automute,
14850 .mixers = { alc861vd_hp_mixer },
14851 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14852 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14853 .dac_nids = alc861vd_dac_nids,
14854 .dig_out_nid = ALC861VD_DIGOUT_NID,
14855 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14856 .channel_mode = alc861vd_3stack_2ch_modes,
14857 .input_mux = &alc861vd_hp_capture_source,
14858 .unsol_event = alc861vd_dallas_unsol_event,
14859 .init_hook = alc861vd_dallas_automute,
14861 [ALC660VD_ASUS_V1S] = {
14862 .mixers = { alc861vd_lenovo_mixer },
14863 .init_verbs = { alc861vd_volume_init_verbs,
14864 alc861vd_3stack_init_verbs,
14865 alc861vd_eapd_verbs,
14866 alc861vd_lenovo_unsol_verbs },
14867 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14868 .dac_nids = alc660vd_dac_nids,
14869 .dig_out_nid = ALC861VD_DIGOUT_NID,
14870 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14871 .channel_mode = alc861vd_3stack_2ch_modes,
14872 .input_mux = &alc861vd_capture_source,
14873 .unsol_event = alc861vd_lenovo_unsol_event,
14874 .init_hook = alc861vd_lenovo_automute,
14879 * BIOS auto configuration
14881 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14882 hda_nid_t nid, int pin_type, int dac_idx)
14884 alc_set_pin_output(codec, nid, pin_type);
14887 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14889 struct alc_spec *spec = codec->spec;
14892 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14893 for (i = 0; i <= HDA_SIDE; i++) {
14894 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14895 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14897 alc861vd_auto_set_output_and_unmute(codec, nid,
14903 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14905 struct alc_spec *spec = codec->spec;
14908 pin = spec->autocfg.hp_pins[0];
14909 if (pin) /* connect to front and use dac 0 */
14910 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14911 pin = spec->autocfg.speaker_pins[0];
14913 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14916 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14917 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14919 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14921 struct alc_spec *spec = codec->spec;
14924 for (i = 0; i < AUTO_PIN_LAST; i++) {
14925 hda_nid_t nid = spec->autocfg.input_pins[i];
14926 if (alc861vd_is_input_pin(nid)) {
14927 alc_set_input_pin(codec, nid, i);
14928 if (nid != ALC861VD_PIN_CD_NID &&
14929 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
14930 snd_hda_codec_write(codec, nid, 0,
14931 AC_VERB_SET_AMP_GAIN_MUTE,
14937 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14939 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14940 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14942 /* add playback controls from the parsed DAC table */
14943 /* Based on ALC880 version. But ALC861VD has separate,
14944 * different NIDs for mute/unmute switch and volume control */
14945 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14946 const struct auto_pin_cfg *cfg)
14949 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14950 hda_nid_t nid_v, nid_s;
14953 for (i = 0; i < cfg->line_outs; i++) {
14954 if (!spec->multiout.dac_nids[i])
14956 nid_v = alc861vd_idx_to_mixer_vol(
14958 spec->multiout.dac_nids[i]));
14959 nid_s = alc861vd_idx_to_mixer_switch(
14961 spec->multiout.dac_nids[i]));
14965 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14966 "Center Playback Volume",
14967 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14971 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14972 "LFE Playback Volume",
14973 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14977 err = add_control(spec, ALC_CTL_BIND_MUTE,
14978 "Center Playback Switch",
14979 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14983 err = add_control(spec, ALC_CTL_BIND_MUTE,
14984 "LFE Playback Switch",
14985 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14990 sprintf(name, "%s Playback Volume", chname[i]);
14991 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14992 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14996 sprintf(name, "%s Playback Switch", chname[i]);
14997 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14998 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
15007 /* add playback controls for speaker and HP outputs */
15008 /* Based on ALC880 version. But ALC861VD has separate,
15009 * different NIDs for mute/unmute switch and volume control */
15010 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15011 hda_nid_t pin, const char *pfx)
15013 hda_nid_t nid_v, nid_s;
15020 if (alc880_is_fixed_pin(pin)) {
15021 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15022 /* specify the DAC as the extra output */
15023 if (!spec->multiout.hp_nid)
15024 spec->multiout.hp_nid = nid_v;
15026 spec->multiout.extra_out_nid[0] = nid_v;
15027 /* control HP volume/switch on the output mixer amp */
15028 nid_v = alc861vd_idx_to_mixer_vol(
15029 alc880_fixed_pin_idx(pin));
15030 nid_s = alc861vd_idx_to_mixer_switch(
15031 alc880_fixed_pin_idx(pin));
15033 sprintf(name, "%s Playback Volume", pfx);
15034 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15035 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15038 sprintf(name, "%s Playback Switch", pfx);
15039 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15040 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15043 } else if (alc880_is_multi_pin(pin)) {
15044 /* set manual connection */
15045 /* we have only a switch on HP-out PIN */
15046 sprintf(name, "%s Playback Switch", pfx);
15047 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15048 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15055 /* parse the BIOS configuration and set up the alc_spec
15056 * return 1 if successful, 0 if the proper config is not found,
15057 * or a negative error code
15058 * Based on ALC880 version - had to change it to override
15059 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15060 static int alc861vd_parse_auto_config(struct hda_codec *codec)
15062 struct alc_spec *spec = codec->spec;
15064 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15066 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15070 if (!spec->autocfg.line_outs)
15071 return 0; /* can't find valid BIOS pin config */
15073 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15076 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15079 err = alc861vd_auto_create_extra_out(spec,
15080 spec->autocfg.speaker_pins[0],
15084 err = alc861vd_auto_create_extra_out(spec,
15085 spec->autocfg.hp_pins[0],
15089 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
15093 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15095 if (spec->autocfg.dig_outs)
15096 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15098 if (spec->kctls.list)
15099 add_mixer(spec, spec->kctls.list);
15101 add_verb(spec, alc861vd_volume_init_verbs);
15103 spec->num_mux_defs = 1;
15104 spec->input_mux = &spec->private_imux[0];
15106 err = alc_auto_add_mic_boost(codec);
15113 /* additional initialization for auto-configuration model */
15114 static void alc861vd_auto_init(struct hda_codec *codec)
15116 struct alc_spec *spec = codec->spec;
15117 alc861vd_auto_init_multi_out(codec);
15118 alc861vd_auto_init_hp_out(codec);
15119 alc861vd_auto_init_analog_input(codec);
15120 alc861vd_auto_init_input_src(codec);
15121 if (spec->unsol_event)
15122 alc_inithook(codec);
15125 static int patch_alc861vd(struct hda_codec *codec)
15127 struct alc_spec *spec;
15128 int err, board_config;
15130 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15134 codec->spec = spec;
15136 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15140 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15141 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
15142 "ALC861VD, trying auto-probe from BIOS...\n");
15143 board_config = ALC861VD_AUTO;
15146 if (board_config == ALC861VD_AUTO) {
15147 /* automatic parse from the BIOS config */
15148 err = alc861vd_parse_auto_config(codec);
15154 "hda_codec: Cannot set up configuration "
15155 "from BIOS. Using base mode...\n");
15156 board_config = ALC861VD_3ST;
15160 err = snd_hda_attach_beep_device(codec, 0x23);
15166 if (board_config != ALC861VD_AUTO)
15167 setup_preset(spec, &alc861vd_presets[board_config]);
15169 if (codec->vendor_id == 0x10ec0660) {
15170 spec->stream_name_analog = "ALC660-VD Analog";
15171 spec->stream_name_digital = "ALC660-VD Digital";
15172 /* always turn on EAPD */
15173 add_verb(spec, alc660vd_eapd_verbs);
15175 spec->stream_name_analog = "ALC861VD Analog";
15176 spec->stream_name_digital = "ALC861VD Digital";
15179 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15180 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15182 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15183 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15185 spec->adc_nids = alc861vd_adc_nids;
15186 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15187 spec->capsrc_nids = alc861vd_capsrc_nids;
15188 spec->capture_style = CAPT_MIX;
15190 set_capture_mixer(spec);
15191 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15193 spec->vmaster_nid = 0x02;
15195 codec->patch_ops = alc_patch_ops;
15197 if (board_config == ALC861VD_AUTO)
15198 spec->init_hook = alc861vd_auto_init;
15199 #ifdef CONFIG_SND_HDA_POWER_SAVE
15200 if (!spec->loopback.amplist)
15201 spec->loopback.amplist = alc861vd_loopbacks;
15203 codec->proc_widget_hook = print_realtek_coef;
15211 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15212 * configuration. Each pin widget can choose any input DACs and a mixer.
15213 * Each ADC is connected from a mixer of all inputs. This makes possible
15214 * 6-channel independent captures.
15216 * In addition, an independent DAC for the multi-playback (not used in this
15219 #define ALC662_DIGOUT_NID 0x06
15220 #define ALC662_DIGIN_NID 0x0a
15222 static hda_nid_t alc662_dac_nids[4] = {
15223 /* front, rear, clfe, rear_surr */
15227 static hda_nid_t alc272_dac_nids[2] = {
15231 static hda_nid_t alc662_adc_nids[1] = {
15236 static hda_nid_t alc272_adc_nids[1] = {
15241 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
15242 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15246 /* FIXME: should be a matrix-type input source selection */
15247 static struct hda_input_mux alc662_capture_source = {
15251 { "Front Mic", 0x1 },
15257 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15265 static struct hda_input_mux alc662_eeepc_capture_source = {
15273 static struct hda_input_mux alc663_capture_source = {
15277 { "Front Mic", 0x1 },
15282 static struct hda_input_mux alc663_m51va_capture_source = {
15285 { "Ext-Mic", 0x0 },
15293 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15300 static struct hda_verb alc662_3ST_ch2_init[] = {
15301 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15302 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15303 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15304 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15311 static struct hda_verb alc662_3ST_ch6_init[] = {
15312 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15313 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15314 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15315 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15316 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15317 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15321 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15322 { 2, alc662_3ST_ch2_init },
15323 { 6, alc662_3ST_ch6_init },
15329 static struct hda_verb alc662_sixstack_ch6_init[] = {
15330 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15331 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15332 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15339 static struct hda_verb alc662_sixstack_ch8_init[] = {
15340 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15341 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15342 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15346 static struct hda_channel_mode alc662_5stack_modes[2] = {
15347 { 2, alc662_sixstack_ch6_init },
15348 { 6, alc662_sixstack_ch8_init },
15351 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15352 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15355 static struct snd_kcontrol_new alc662_base_mixer[] = {
15356 /* output mixer control */
15357 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15358 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15359 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15360 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15361 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15362 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15363 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15364 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15367 /*Input mixer control */
15368 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15369 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15370 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15371 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15372 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15373 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15374 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15375 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15379 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15380 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15381 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15383 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15384 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15385 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15386 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15387 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15388 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15389 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15390 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15394 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15395 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15396 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15397 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15398 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15399 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15400 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15401 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15402 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15403 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15404 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15405 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15406 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15407 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15408 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15409 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15410 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15411 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15415 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15416 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15417 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15418 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15419 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15420 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15421 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15422 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15423 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15424 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15428 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15429 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15431 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15432 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15434 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15435 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15436 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15438 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15439 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15440 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15444 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15445 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15446 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15447 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15448 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
15449 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15450 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15451 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
15452 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
15453 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15454 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15455 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15456 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15457 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15458 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15462 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15463 .ops = &snd_hda_bind_vol,
15465 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15466 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15471 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15472 .ops = &snd_hda_bind_sw,
15474 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15475 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15480 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15481 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15482 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15483 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15484 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15488 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15489 .ops = &snd_hda_bind_sw,
15491 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15492 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15493 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15498 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15499 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15500 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15501 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15502 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15503 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15504 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15509 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15510 .ops = &snd_hda_bind_sw,
15512 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15513 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15514 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15519 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15520 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15521 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15523 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15524 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15525 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15529 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15530 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15531 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15532 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15534 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15535 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15536 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15540 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15541 .ops = &snd_hda_bind_vol,
15543 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15544 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15549 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15550 .ops = &snd_hda_bind_sw,
15552 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15553 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15558 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15559 HDA_BIND_VOL("Master Playback Volume",
15560 &alc663_asus_two_bind_master_vol),
15561 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15562 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15563 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15564 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15565 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15569 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15570 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15571 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15572 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15573 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15575 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15579 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15580 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15581 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15582 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15583 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15584 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15586 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15587 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15588 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15589 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15593 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15594 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15595 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15596 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15598 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15599 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15600 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15601 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15602 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15603 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15607 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15609 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15610 .name = "Channel Mode",
15611 .info = alc_ch_mode_info,
15612 .get = alc_ch_mode_get,
15613 .put = alc_ch_mode_put,
15618 static struct hda_verb alc662_init_verbs[] = {
15619 /* ADC: mute amp left and right */
15620 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15621 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15622 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15624 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15625 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15626 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15627 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15628 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15630 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15631 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15632 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15633 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15634 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15635 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15637 /* Front Pin: output 0 (0x0c) */
15638 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15639 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15641 /* Rear Pin: output 1 (0x0d) */
15642 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15645 /* CLFE Pin: output 2 (0x0e) */
15646 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15647 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15649 /* Mic (rear) pin: input vref at 80% */
15650 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15651 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15652 /* Front Mic pin: input vref at 80% */
15653 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15654 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15655 /* Line In pin: input */
15656 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15657 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15658 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15659 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15660 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15661 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15662 /* CD pin widget for input */
15663 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15665 /* FIXME: use matrix-type input source selection */
15666 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15668 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15669 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15671 /* always trun on EAPD */
15672 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15673 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15678 static struct hda_verb alc662_sue_init_verbs[] = {
15679 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15680 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15684 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15685 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15686 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15690 /* Set Unsolicited Event*/
15691 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15692 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15693 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15698 * generic initialization of ADC, input mixers and output mixers
15700 static struct hda_verb alc662_auto_init_verbs[] = {
15702 * Unmute ADC and set the default input to mic-in
15704 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15705 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15707 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15709 * Note: PASD motherboards uses the Line In 2 as the input for front
15710 * panel mic (mic 2)
15712 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15713 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15714 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15715 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15716 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15717 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15720 * Set up output mixers (0x0c - 0x0f)
15722 /* set vol=0 to output mixers */
15723 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15724 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15725 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15727 /* set up input amps for analog loopback */
15728 /* Amp Indices: DAC = 0, mixer = 1 */
15729 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15730 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15731 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15732 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15733 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15734 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15737 /* FIXME: use matrix-type input source selection */
15738 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15740 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15741 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15745 /* additional verbs for ALC663 */
15746 static struct hda_verb alc663_auto_init_verbs[] = {
15747 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15748 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15752 static struct hda_verb alc663_m51va_init_verbs[] = {
15753 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15754 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15755 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15756 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15757 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15758 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15759 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15760 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15761 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15765 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15766 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15767 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15768 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15771 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15772 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15776 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15777 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15778 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15779 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15780 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15781 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15782 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15783 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15784 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15788 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15789 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15790 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15791 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15792 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15793 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15794 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15795 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15799 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15800 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15801 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15802 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15803 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15804 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15805 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15806 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15807 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15808 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15809 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15810 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15811 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15815 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15816 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15817 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15818 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15819 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15820 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15821 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15822 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15823 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15824 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15825 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15826 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15827 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15831 static struct hda_verb alc663_g71v_init_verbs[] = {
15832 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15833 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15834 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15836 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15837 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15838 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15840 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15841 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15842 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15846 static struct hda_verb alc663_g50v_init_verbs[] = {
15847 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15848 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15849 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15851 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15852 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15856 static struct hda_verb alc662_ecs_init_verbs[] = {
15857 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15858 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15859 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15860 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15864 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15865 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15866 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15867 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15868 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15869 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15870 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15871 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15872 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15873 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15874 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15875 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15879 static struct hda_verb alc272_dell_init_verbs[] = {
15880 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15881 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15882 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15883 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15884 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15885 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15886 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15888 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15889 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15890 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15894 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15895 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15896 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15900 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
15901 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
15902 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
15906 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15908 unsigned int present;
15909 unsigned char bits;
15911 present = snd_hda_codec_read(codec, 0x14, 0,
15912 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15913 bits = present ? HDA_AMP_MUTE : 0;
15914 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15915 HDA_AMP_MUTE, bits);
15918 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15920 unsigned int present;
15921 unsigned char bits;
15923 present = snd_hda_codec_read(codec, 0x1b, 0,
15924 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15925 bits = present ? HDA_AMP_MUTE : 0;
15926 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15927 HDA_AMP_MUTE, bits);
15928 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15929 HDA_AMP_MUTE, bits);
15932 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15935 if ((res >> 26) == ALC880_HP_EVENT)
15936 alc662_lenovo_101e_all_automute(codec);
15937 if ((res >> 26) == ALC880_FRONT_EVENT)
15938 alc662_lenovo_101e_ispeaker_automute(codec);
15941 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15943 unsigned int present;
15945 present = snd_hda_codec_read(codec, 0x18, 0,
15946 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15947 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15948 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15949 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15950 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15951 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15952 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15953 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15954 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15957 /* unsolicited event for HP jack sensing */
15958 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15961 if ((res >> 26) == ALC880_HP_EVENT)
15962 alc262_hippo1_automute( codec );
15964 if ((res >> 26) == ALC880_MIC_EVENT)
15965 alc662_eeepc_mic_automute(codec);
15968 static void alc662_eeepc_inithook(struct hda_codec *codec)
15970 alc262_hippo1_automute( codec );
15971 alc662_eeepc_mic_automute(codec);
15974 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15977 unsigned int present;
15979 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15980 present = snd_hda_codec_read(codec, 0x14, 0,
15981 AC_VERB_GET_PIN_SENSE, 0);
15982 present = (present & 0x80000000) != 0;
15984 /* mute internal speaker */
15985 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15986 HDA_AMP_MUTE, HDA_AMP_MUTE);
15988 /* unmute internal speaker if necessary */
15989 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15990 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15991 HDA_AMP_MUTE, mute);
15995 /* unsolicited event for HP jack sensing */
15996 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15999 if ((res >> 26) == ALC880_HP_EVENT)
16000 alc662_eeepc_ep20_automute(codec);
16003 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
16005 alc662_eeepc_ep20_automute(codec);
16008 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16010 unsigned int present;
16011 unsigned char bits;
16013 present = snd_hda_codec_read(codec, 0x21, 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, 0x0c, HDA_INPUT, 0,
16018 AMP_IN_MUTE(0), bits);
16019 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16020 AMP_IN_MUTE(0), bits);
16023 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16025 unsigned int present;
16026 unsigned char bits;
16028 present = snd_hda_codec_read(codec, 0x21, 0,
16029 AC_VERB_GET_PIN_SENSE, 0)
16030 & AC_PINSENSE_PRESENCE;
16031 bits = present ? HDA_AMP_MUTE : 0;
16032 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16033 AMP_IN_MUTE(0), bits);
16034 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16035 AMP_IN_MUTE(0), bits);
16036 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16037 AMP_IN_MUTE(0), bits);
16038 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16039 AMP_IN_MUTE(0), bits);
16042 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16044 unsigned int present;
16045 unsigned char bits;
16047 present = snd_hda_codec_read(codec, 0x15, 0,
16048 AC_VERB_GET_PIN_SENSE, 0)
16049 & AC_PINSENSE_PRESENCE;
16050 bits = present ? HDA_AMP_MUTE : 0;
16051 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16052 AMP_IN_MUTE(0), bits);
16053 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16054 AMP_IN_MUTE(0), bits);
16055 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16056 AMP_IN_MUTE(0), bits);
16057 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16058 AMP_IN_MUTE(0), bits);
16061 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16063 unsigned int present;
16064 unsigned char bits;
16066 present = snd_hda_codec_read(codec, 0x1b, 0,
16067 AC_VERB_GET_PIN_SENSE, 0)
16068 & AC_PINSENSE_PRESENCE;
16069 bits = present ? 0 : PIN_OUT;
16070 snd_hda_codec_write(codec, 0x14, 0,
16071 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16074 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16076 unsigned int present1, present2;
16078 present1 = snd_hda_codec_read(codec, 0x21, 0,
16079 AC_VERB_GET_PIN_SENSE, 0)
16080 & AC_PINSENSE_PRESENCE;
16081 present2 = snd_hda_codec_read(codec, 0x15, 0,
16082 AC_VERB_GET_PIN_SENSE, 0)
16083 & AC_PINSENSE_PRESENCE;
16085 if (present1 || present2) {
16086 snd_hda_codec_write_cache(codec, 0x14, 0,
16087 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16089 snd_hda_codec_write_cache(codec, 0x14, 0,
16090 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16094 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16096 unsigned int present1, present2;
16098 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16099 AC_VERB_GET_PIN_SENSE, 0)
16100 & AC_PINSENSE_PRESENCE;
16101 present2 = snd_hda_codec_read(codec, 0x15, 0,
16102 AC_VERB_GET_PIN_SENSE, 0)
16103 & AC_PINSENSE_PRESENCE;
16105 if (present1 || present2) {
16106 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16107 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16108 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16109 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16111 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16112 AMP_IN_MUTE(0), 0);
16113 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16114 AMP_IN_MUTE(0), 0);
16118 static void alc663_m51va_mic_automute(struct hda_codec *codec)
16120 unsigned int present;
16122 present = snd_hda_codec_read(codec, 0x18, 0,
16123 AC_VERB_GET_PIN_SENSE, 0)
16124 & AC_PINSENSE_PRESENCE;
16125 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16126 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16127 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16128 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16129 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16130 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16131 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16132 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16135 static void alc663_m51va_unsol_event(struct hda_codec *codec,
16138 switch (res >> 26) {
16139 case ALC880_HP_EVENT:
16140 alc663_m51va_speaker_automute(codec);
16142 case ALC880_MIC_EVENT:
16143 alc663_m51va_mic_automute(codec);
16148 static void alc663_m51va_inithook(struct hda_codec *codec)
16150 alc663_m51va_speaker_automute(codec);
16151 alc663_m51va_mic_automute(codec);
16154 /* ***************** Mode1 ******************************/
16155 static void alc663_mode1_unsol_event(struct hda_codec *codec,
16158 switch (res >> 26) {
16159 case ALC880_HP_EVENT:
16160 alc663_m51va_speaker_automute(codec);
16162 case ALC880_MIC_EVENT:
16163 alc662_eeepc_mic_automute(codec);
16168 static void alc663_mode1_inithook(struct hda_codec *codec)
16170 alc663_m51va_speaker_automute(codec);
16171 alc662_eeepc_mic_automute(codec);
16173 /* ***************** Mode2 ******************************/
16174 static void alc662_mode2_unsol_event(struct hda_codec *codec,
16177 switch (res >> 26) {
16178 case ALC880_HP_EVENT:
16179 alc662_f5z_speaker_automute(codec);
16181 case ALC880_MIC_EVENT:
16182 alc662_eeepc_mic_automute(codec);
16187 static void alc662_mode2_inithook(struct hda_codec *codec)
16189 alc662_f5z_speaker_automute(codec);
16190 alc662_eeepc_mic_automute(codec);
16192 /* ***************** Mode3 ******************************/
16193 static void alc663_mode3_unsol_event(struct hda_codec *codec,
16196 switch (res >> 26) {
16197 case ALC880_HP_EVENT:
16198 alc663_two_hp_m1_speaker_automute(codec);
16200 case ALC880_MIC_EVENT:
16201 alc662_eeepc_mic_automute(codec);
16206 static void alc663_mode3_inithook(struct hda_codec *codec)
16208 alc663_two_hp_m1_speaker_automute(codec);
16209 alc662_eeepc_mic_automute(codec);
16211 /* ***************** Mode4 ******************************/
16212 static void alc663_mode4_unsol_event(struct hda_codec *codec,
16215 switch (res >> 26) {
16216 case ALC880_HP_EVENT:
16217 alc663_21jd_two_speaker_automute(codec);
16219 case ALC880_MIC_EVENT:
16220 alc662_eeepc_mic_automute(codec);
16225 static void alc663_mode4_inithook(struct hda_codec *codec)
16227 alc663_21jd_two_speaker_automute(codec);
16228 alc662_eeepc_mic_automute(codec);
16230 /* ***************** Mode5 ******************************/
16231 static void alc663_mode5_unsol_event(struct hda_codec *codec,
16234 switch (res >> 26) {
16235 case ALC880_HP_EVENT:
16236 alc663_15jd_two_speaker_automute(codec);
16238 case ALC880_MIC_EVENT:
16239 alc662_eeepc_mic_automute(codec);
16244 static void alc663_mode5_inithook(struct hda_codec *codec)
16246 alc663_15jd_two_speaker_automute(codec);
16247 alc662_eeepc_mic_automute(codec);
16249 /* ***************** Mode6 ******************************/
16250 static void alc663_mode6_unsol_event(struct hda_codec *codec,
16253 switch (res >> 26) {
16254 case ALC880_HP_EVENT:
16255 alc663_two_hp_m2_speaker_automute(codec);
16257 case ALC880_MIC_EVENT:
16258 alc662_eeepc_mic_automute(codec);
16263 static void alc663_mode6_inithook(struct hda_codec *codec)
16265 alc663_two_hp_m2_speaker_automute(codec);
16266 alc662_eeepc_mic_automute(codec);
16269 static void alc663_g71v_hp_automute(struct hda_codec *codec)
16271 unsigned int present;
16272 unsigned char bits;
16274 present = snd_hda_codec_read(codec, 0x21, 0,
16275 AC_VERB_GET_PIN_SENSE, 0)
16276 & AC_PINSENSE_PRESENCE;
16277 bits = present ? HDA_AMP_MUTE : 0;
16278 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16279 HDA_AMP_MUTE, bits);
16280 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16281 HDA_AMP_MUTE, bits);
16284 static void alc663_g71v_front_automute(struct hda_codec *codec)
16286 unsigned int present;
16287 unsigned char bits;
16289 present = snd_hda_codec_read(codec, 0x15, 0,
16290 AC_VERB_GET_PIN_SENSE, 0)
16291 & AC_PINSENSE_PRESENCE;
16292 bits = present ? HDA_AMP_MUTE : 0;
16293 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16294 HDA_AMP_MUTE, bits);
16297 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16300 switch (res >> 26) {
16301 case ALC880_HP_EVENT:
16302 alc663_g71v_hp_automute(codec);
16304 case ALC880_FRONT_EVENT:
16305 alc663_g71v_front_automute(codec);
16307 case ALC880_MIC_EVENT:
16308 alc662_eeepc_mic_automute(codec);
16313 static void alc663_g71v_inithook(struct hda_codec *codec)
16315 alc663_g71v_front_automute(codec);
16316 alc663_g71v_hp_automute(codec);
16317 alc662_eeepc_mic_automute(codec);
16320 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16323 switch (res >> 26) {
16324 case ALC880_HP_EVENT:
16325 alc663_m51va_speaker_automute(codec);
16327 case ALC880_MIC_EVENT:
16328 alc662_eeepc_mic_automute(codec);
16333 static void alc663_g50v_inithook(struct hda_codec *codec)
16335 alc663_m51va_speaker_automute(codec);
16336 alc662_eeepc_mic_automute(codec);
16339 /* bind hp and internal speaker mute (with plug check) */
16340 static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
16341 struct snd_ctl_elem_value *ucontrol)
16343 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
16344 long *valp = ucontrol->value.integer.value;
16347 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
16349 valp[0] ? 0 : HDA_AMP_MUTE);
16350 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
16352 valp[1] ? 0 : HDA_AMP_MUTE);
16354 alc262_hippo1_automute(codec);
16358 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16359 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16361 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16362 .name = "Master Playback Switch",
16363 .info = snd_hda_mixer_amp_switch_info,
16364 .get = snd_hda_mixer_amp_switch_get,
16365 .put = alc662_ecs_master_sw_put,
16366 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16369 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16370 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16371 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16373 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16374 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16375 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16379 #ifdef CONFIG_SND_HDA_POWER_SAVE
16380 #define alc662_loopbacks alc880_loopbacks
16384 /* pcm configuration: identiacal with ALC880 */
16385 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16386 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16387 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16388 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16391 * configuration and preset
16393 static const char *alc662_models[ALC662_MODEL_LAST] = {
16394 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16395 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16396 [ALC662_3ST_6ch] = "3stack-6ch",
16397 [ALC662_5ST_DIG] = "6stack-dig",
16398 [ALC662_LENOVO_101E] = "lenovo-101e",
16399 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16400 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16401 [ALC662_ECS] = "ecs",
16402 [ALC663_ASUS_M51VA] = "m51va",
16403 [ALC663_ASUS_G71V] = "g71v",
16404 [ALC663_ASUS_H13] = "h13",
16405 [ALC663_ASUS_G50V] = "g50v",
16406 [ALC663_ASUS_MODE1] = "asus-mode1",
16407 [ALC662_ASUS_MODE2] = "asus-mode2",
16408 [ALC663_ASUS_MODE3] = "asus-mode3",
16409 [ALC663_ASUS_MODE4] = "asus-mode4",
16410 [ALC663_ASUS_MODE5] = "asus-mode5",
16411 [ALC663_ASUS_MODE6] = "asus-mode6",
16412 [ALC662_AUTO] = "auto",
16415 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16416 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16417 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16418 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16419 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16420 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16421 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16422 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16423 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16424 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16425 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16426 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16427 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16428 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16429 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16430 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16431 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16432 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16433 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16434 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16435 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16436 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16437 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16438 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16439 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16440 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16441 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16442 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16443 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16444 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16445 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16446 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16447 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16448 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16449 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16450 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16451 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16452 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16453 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16454 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16455 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16456 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16457 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16458 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16459 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16460 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16461 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16462 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16463 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16464 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16465 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16466 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16467 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16468 ALC662_3ST_6ch_DIG),
16469 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16470 ALC662_3ST_6ch_DIG),
16471 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16472 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16473 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16474 ALC662_3ST_6ch_DIG),
16475 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16480 static struct alc_config_preset alc662_presets[] = {
16481 [ALC662_3ST_2ch_DIG] = {
16482 .mixers = { alc662_3ST_2ch_mixer },
16483 .init_verbs = { alc662_init_verbs },
16484 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16485 .dac_nids = alc662_dac_nids,
16486 .dig_out_nid = ALC662_DIGOUT_NID,
16487 .dig_in_nid = ALC662_DIGIN_NID,
16488 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16489 .channel_mode = alc662_3ST_2ch_modes,
16490 .input_mux = &alc662_capture_source,
16492 [ALC662_3ST_6ch_DIG] = {
16493 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16494 .init_verbs = { alc662_init_verbs },
16495 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16496 .dac_nids = alc662_dac_nids,
16497 .dig_out_nid = ALC662_DIGOUT_NID,
16498 .dig_in_nid = ALC662_DIGIN_NID,
16499 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16500 .channel_mode = alc662_3ST_6ch_modes,
16502 .input_mux = &alc662_capture_source,
16504 [ALC662_3ST_6ch] = {
16505 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16506 .init_verbs = { alc662_init_verbs },
16507 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16508 .dac_nids = alc662_dac_nids,
16509 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16510 .channel_mode = alc662_3ST_6ch_modes,
16512 .input_mux = &alc662_capture_source,
16514 [ALC662_5ST_DIG] = {
16515 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16516 .init_verbs = { alc662_init_verbs },
16517 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16518 .dac_nids = alc662_dac_nids,
16519 .dig_out_nid = ALC662_DIGOUT_NID,
16520 .dig_in_nid = ALC662_DIGIN_NID,
16521 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16522 .channel_mode = alc662_5stack_modes,
16523 .input_mux = &alc662_capture_source,
16525 [ALC662_LENOVO_101E] = {
16526 .mixers = { alc662_lenovo_101e_mixer },
16527 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16528 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16529 .dac_nids = alc662_dac_nids,
16530 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16531 .channel_mode = alc662_3ST_2ch_modes,
16532 .input_mux = &alc662_lenovo_101e_capture_source,
16533 .unsol_event = alc662_lenovo_101e_unsol_event,
16534 .init_hook = alc662_lenovo_101e_all_automute,
16536 [ALC662_ASUS_EEEPC_P701] = {
16537 .mixers = { alc662_eeepc_p701_mixer },
16538 .init_verbs = { alc662_init_verbs,
16539 alc662_eeepc_sue_init_verbs },
16540 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16541 .dac_nids = alc662_dac_nids,
16542 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16543 .channel_mode = alc662_3ST_2ch_modes,
16544 .input_mux = &alc662_eeepc_capture_source,
16545 .unsol_event = alc662_eeepc_unsol_event,
16546 .init_hook = alc662_eeepc_inithook,
16548 [ALC662_ASUS_EEEPC_EP20] = {
16549 .mixers = { alc662_eeepc_ep20_mixer,
16550 alc662_chmode_mixer },
16551 .init_verbs = { alc662_init_verbs,
16552 alc662_eeepc_ep20_sue_init_verbs },
16553 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16554 .dac_nids = alc662_dac_nids,
16555 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16556 .channel_mode = alc662_3ST_6ch_modes,
16557 .input_mux = &alc662_lenovo_101e_capture_source,
16558 .unsol_event = alc662_eeepc_ep20_unsol_event,
16559 .init_hook = alc662_eeepc_ep20_inithook,
16562 .mixers = { alc662_ecs_mixer },
16563 .init_verbs = { alc662_init_verbs,
16564 alc662_ecs_init_verbs },
16565 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16566 .dac_nids = alc662_dac_nids,
16567 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16568 .channel_mode = alc662_3ST_2ch_modes,
16569 .input_mux = &alc662_eeepc_capture_source,
16570 .unsol_event = alc662_eeepc_unsol_event,
16571 .init_hook = alc662_eeepc_inithook,
16573 [ALC663_ASUS_M51VA] = {
16574 .mixers = { alc663_m51va_mixer },
16575 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16576 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16577 .dac_nids = alc662_dac_nids,
16578 .dig_out_nid = ALC662_DIGOUT_NID,
16579 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16580 .channel_mode = alc662_3ST_2ch_modes,
16581 .input_mux = &alc663_m51va_capture_source,
16582 .unsol_event = alc663_m51va_unsol_event,
16583 .init_hook = alc663_m51va_inithook,
16585 [ALC663_ASUS_G71V] = {
16586 .mixers = { alc663_g71v_mixer },
16587 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16588 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16589 .dac_nids = alc662_dac_nids,
16590 .dig_out_nid = ALC662_DIGOUT_NID,
16591 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16592 .channel_mode = alc662_3ST_2ch_modes,
16593 .input_mux = &alc662_eeepc_capture_source,
16594 .unsol_event = alc663_g71v_unsol_event,
16595 .init_hook = alc663_g71v_inithook,
16597 [ALC663_ASUS_H13] = {
16598 .mixers = { alc663_m51va_mixer },
16599 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16600 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16601 .dac_nids = alc662_dac_nids,
16602 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16603 .channel_mode = alc662_3ST_2ch_modes,
16604 .input_mux = &alc663_m51va_capture_source,
16605 .unsol_event = alc663_m51va_unsol_event,
16606 .init_hook = alc663_m51va_inithook,
16608 [ALC663_ASUS_G50V] = {
16609 .mixers = { alc663_g50v_mixer },
16610 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16611 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16612 .dac_nids = alc662_dac_nids,
16613 .dig_out_nid = ALC662_DIGOUT_NID,
16614 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16615 .channel_mode = alc662_3ST_6ch_modes,
16616 .input_mux = &alc663_capture_source,
16617 .unsol_event = alc663_g50v_unsol_event,
16618 .init_hook = alc663_g50v_inithook,
16620 [ALC663_ASUS_MODE1] = {
16621 .mixers = { alc663_m51va_mixer },
16622 .cap_mixer = alc662_auto_capture_mixer,
16623 .init_verbs = { alc662_init_verbs,
16624 alc663_21jd_amic_init_verbs },
16625 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16627 .dac_nids = alc662_dac_nids,
16628 .dig_out_nid = ALC662_DIGOUT_NID,
16629 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16630 .channel_mode = alc662_3ST_2ch_modes,
16631 .input_mux = &alc662_eeepc_capture_source,
16632 .unsol_event = alc663_mode1_unsol_event,
16633 .init_hook = alc663_mode1_inithook,
16635 [ALC662_ASUS_MODE2] = {
16636 .mixers = { alc662_1bjd_mixer },
16637 .cap_mixer = alc662_auto_capture_mixer,
16638 .init_verbs = { alc662_init_verbs,
16639 alc662_1bjd_amic_init_verbs },
16640 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16641 .dac_nids = alc662_dac_nids,
16642 .dig_out_nid = ALC662_DIGOUT_NID,
16643 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16644 .channel_mode = alc662_3ST_2ch_modes,
16645 .input_mux = &alc662_eeepc_capture_source,
16646 .unsol_event = alc662_mode2_unsol_event,
16647 .init_hook = alc662_mode2_inithook,
16649 [ALC663_ASUS_MODE3] = {
16650 .mixers = { alc663_two_hp_m1_mixer },
16651 .cap_mixer = alc662_auto_capture_mixer,
16652 .init_verbs = { alc662_init_verbs,
16653 alc663_two_hp_amic_m1_init_verbs },
16654 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16656 .dac_nids = alc662_dac_nids,
16657 .dig_out_nid = ALC662_DIGOUT_NID,
16658 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16659 .channel_mode = alc662_3ST_2ch_modes,
16660 .input_mux = &alc662_eeepc_capture_source,
16661 .unsol_event = alc663_mode3_unsol_event,
16662 .init_hook = alc663_mode3_inithook,
16664 [ALC663_ASUS_MODE4] = {
16665 .mixers = { alc663_asus_21jd_clfe_mixer },
16666 .cap_mixer = alc662_auto_capture_mixer,
16667 .init_verbs = { alc662_init_verbs,
16668 alc663_21jd_amic_init_verbs},
16669 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16671 .dac_nids = alc662_dac_nids,
16672 .dig_out_nid = ALC662_DIGOUT_NID,
16673 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16674 .channel_mode = alc662_3ST_2ch_modes,
16675 .input_mux = &alc662_eeepc_capture_source,
16676 .unsol_event = alc663_mode4_unsol_event,
16677 .init_hook = alc663_mode4_inithook,
16679 [ALC663_ASUS_MODE5] = {
16680 .mixers = { alc663_asus_15jd_clfe_mixer },
16681 .cap_mixer = alc662_auto_capture_mixer,
16682 .init_verbs = { alc662_init_verbs,
16683 alc663_15jd_amic_init_verbs },
16684 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16686 .dac_nids = alc662_dac_nids,
16687 .dig_out_nid = ALC662_DIGOUT_NID,
16688 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16689 .channel_mode = alc662_3ST_2ch_modes,
16690 .input_mux = &alc662_eeepc_capture_source,
16691 .unsol_event = alc663_mode5_unsol_event,
16692 .init_hook = alc663_mode5_inithook,
16694 [ALC663_ASUS_MODE6] = {
16695 .mixers = { alc663_two_hp_m2_mixer },
16696 .cap_mixer = alc662_auto_capture_mixer,
16697 .init_verbs = { alc662_init_verbs,
16698 alc663_two_hp_amic_m2_init_verbs },
16699 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16701 .dac_nids = alc662_dac_nids,
16702 .dig_out_nid = ALC662_DIGOUT_NID,
16703 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16704 .channel_mode = alc662_3ST_2ch_modes,
16705 .input_mux = &alc662_eeepc_capture_source,
16706 .unsol_event = alc663_mode6_unsol_event,
16707 .init_hook = alc663_mode6_inithook,
16710 .mixers = { alc663_m51va_mixer },
16711 .cap_mixer = alc272_auto_capture_mixer,
16712 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16713 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16714 .dac_nids = alc662_dac_nids,
16715 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16716 .adc_nids = alc272_adc_nids,
16717 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16718 .capsrc_nids = alc272_capsrc_nids,
16719 .channel_mode = alc662_3ST_2ch_modes,
16720 .input_mux = &alc663_m51va_capture_source,
16721 .unsol_event = alc663_m51va_unsol_event,
16722 .init_hook = alc663_m51va_inithook,
16724 [ALC272_DELL_ZM1] = {
16725 .mixers = { alc663_m51va_mixer },
16726 .cap_mixer = alc662_auto_capture_mixer,
16727 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16728 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16729 .dac_nids = alc662_dac_nids,
16730 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16731 .adc_nids = alc662_adc_nids,
16732 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16733 .capsrc_nids = alc662_capsrc_nids,
16734 .channel_mode = alc662_3ST_2ch_modes,
16735 .input_mux = &alc663_m51va_capture_source,
16736 .unsol_event = alc663_m51va_unsol_event,
16737 .init_hook = alc663_m51va_inithook,
16743 * BIOS auto configuration
16746 /* add playback controls from the parsed DAC table */
16747 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16748 const struct auto_pin_cfg *cfg)
16751 static const char *chname[4] = {
16752 "Front", "Surround", NULL /*CLFE*/, "Side"
16757 for (i = 0; i < cfg->line_outs; i++) {
16758 if (!spec->multiout.dac_nids[i])
16760 nid = alc880_idx_to_dac(i);
16763 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16764 "Center Playback Volume",
16765 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16769 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16770 "LFE Playback Volume",
16771 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16775 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16776 "Center Playback Switch",
16777 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16781 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16782 "LFE Playback Switch",
16783 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16788 sprintf(name, "%s Playback Volume", chname[i]);
16789 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16790 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16794 sprintf(name, "%s Playback Switch", chname[i]);
16795 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16796 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16805 /* add playback controls for speaker and HP outputs */
16806 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16817 /* ALC663 has a mono output pin on 0x17 */
16818 sprintf(name, "%s Playback Switch", pfx);
16819 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16820 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16824 if (alc880_is_fixed_pin(pin)) {
16825 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16826 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
16827 /* specify the DAC as the extra output */
16828 if (!spec->multiout.hp_nid)
16829 spec->multiout.hp_nid = nid;
16831 spec->multiout.extra_out_nid[0] = nid;
16832 /* control HP volume/switch on the output mixer amp */
16833 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16834 sprintf(name, "%s Playback Volume", pfx);
16835 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16836 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16839 sprintf(name, "%s Playback Switch", pfx);
16840 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16841 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16844 } else if (alc880_is_multi_pin(pin)) {
16845 /* set manual connection */
16846 /* we have only a switch on HP-out PIN */
16847 sprintf(name, "%s Playback Switch", pfx);
16848 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16849 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16856 /* return the index of the src widget from the connection list of the nid.
16857 * return -1 if not found
16859 static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16862 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16865 conns = snd_hda_get_connections(codec, nid, conn_list,
16866 ARRAY_SIZE(conn_list));
16869 for (i = 0; i < conns; i++)
16870 if (conn_list[i] == src)
16875 static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16877 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
16878 return (pincap & AC_PINCAP_IN) != 0;
16881 /* create playback/capture controls for input pins */
16882 static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
16883 const struct auto_pin_cfg *cfg)
16885 struct alc_spec *spec = codec->spec;
16886 struct hda_input_mux *imux = &spec->private_imux[0];
16889 for (i = 0; i < AUTO_PIN_LAST; i++) {
16890 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
16891 idx = alc662_input_pin_idx(codec, 0x0b,
16892 cfg->input_pins[i]);
16894 err = new_analog_input(spec, cfg->input_pins[i],
16895 auto_pin_cfg_labels[i],
16900 idx = alc662_input_pin_idx(codec, 0x22,
16901 cfg->input_pins[i]);
16903 imux->items[imux->num_items].label =
16904 auto_pin_cfg_labels[i];
16905 imux->items[imux->num_items].index = idx;
16913 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16914 hda_nid_t nid, int pin_type,
16917 alc_set_pin_output(codec, nid, pin_type);
16918 /* need the manual connection? */
16919 if (alc880_is_multi_pin(nid)) {
16920 struct alc_spec *spec = codec->spec;
16921 int idx = alc880_multi_pin_idx(nid);
16922 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16923 AC_VERB_SET_CONNECT_SEL,
16924 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16928 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16930 struct alc_spec *spec = codec->spec;
16933 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16934 for (i = 0; i <= HDA_SIDE; i++) {
16935 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16936 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16938 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16943 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16945 struct alc_spec *spec = codec->spec;
16948 pin = spec->autocfg.hp_pins[0];
16949 if (pin) /* connect to front */
16951 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16952 pin = spec->autocfg.speaker_pins[0];
16954 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16957 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16959 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16961 struct alc_spec *spec = codec->spec;
16964 for (i = 0; i < AUTO_PIN_LAST; i++) {
16965 hda_nid_t nid = spec->autocfg.input_pins[i];
16966 if (alc662_is_input_pin(codec, nid)) {
16967 alc_set_input_pin(codec, nid, i);
16968 if (nid != ALC662_PIN_CD_NID &&
16969 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
16970 snd_hda_codec_write(codec, nid, 0,
16971 AC_VERB_SET_AMP_GAIN_MUTE,
16977 #define alc662_auto_init_input_src alc882_auto_init_input_src
16979 static int alc662_parse_auto_config(struct hda_codec *codec)
16981 struct alc_spec *spec = codec->spec;
16983 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16985 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16989 if (!spec->autocfg.line_outs)
16990 return 0; /* can't find valid BIOS pin config */
16992 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16995 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16998 err = alc662_auto_create_extra_out(spec,
16999 spec->autocfg.speaker_pins[0],
17003 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
17007 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
17011 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17013 if (spec->autocfg.dig_outs)
17014 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17016 if (spec->kctls.list)
17017 add_mixer(spec, spec->kctls.list);
17019 spec->num_mux_defs = 1;
17020 spec->input_mux = &spec->private_imux[0];
17022 add_verb(spec, alc662_auto_init_verbs);
17023 if (codec->vendor_id == 0x10ec0663)
17024 add_verb(spec, alc663_auto_init_verbs);
17026 err = alc_auto_add_mic_boost(codec);
17033 /* additional initialization for auto-configuration model */
17034 static void alc662_auto_init(struct hda_codec *codec)
17036 struct alc_spec *spec = codec->spec;
17037 alc662_auto_init_multi_out(codec);
17038 alc662_auto_init_hp_out(codec);
17039 alc662_auto_init_analog_input(codec);
17040 alc662_auto_init_input_src(codec);
17041 if (spec->unsol_event)
17042 alc_inithook(codec);
17045 static int patch_alc662(struct hda_codec *codec)
17047 struct alc_spec *spec;
17048 int err, board_config;
17050 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17054 codec->spec = spec;
17056 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17058 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17061 if (board_config < 0) {
17062 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
17063 "trying auto-probe from BIOS...\n");
17064 board_config = ALC662_AUTO;
17067 if (board_config == ALC662_AUTO) {
17068 /* automatic parse from the BIOS config */
17069 err = alc662_parse_auto_config(codec);
17075 "hda_codec: Cannot set up configuration "
17076 "from BIOS. Using base mode...\n");
17077 board_config = ALC662_3ST_2ch_DIG;
17081 err = snd_hda_attach_beep_device(codec, 0x1);
17087 if (board_config != ALC662_AUTO)
17088 setup_preset(spec, &alc662_presets[board_config]);
17090 if (codec->vendor_id == 0x10ec0663) {
17091 spec->stream_name_analog = "ALC663 Analog";
17092 spec->stream_name_digital = "ALC663 Digital";
17093 } else if (codec->vendor_id == 0x10ec0272) {
17094 spec->stream_name_analog = "ALC272 Analog";
17095 spec->stream_name_digital = "ALC272 Digital";
17097 spec->stream_name_analog = "ALC662 Analog";
17098 spec->stream_name_digital = "ALC662 Digital";
17101 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17102 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17104 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17105 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17107 spec->adc_nids = alc662_adc_nids;
17108 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17109 spec->capsrc_nids = alc662_capsrc_nids;
17110 spec->capture_style = CAPT_MIX;
17112 if (!spec->cap_mixer)
17113 set_capture_mixer(spec);
17114 if (codec->vendor_id == 0x10ec0662)
17115 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17117 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17119 spec->vmaster_nid = 0x02;
17121 codec->patch_ops = alc_patch_ops;
17122 if (board_config == ALC662_AUTO)
17123 spec->init_hook = alc662_auto_init;
17124 #ifdef CONFIG_SND_HDA_POWER_SAVE
17125 if (!spec->loopback.amplist)
17126 spec->loopback.amplist = alc662_loopbacks;
17128 codec->proc_widget_hook = print_realtek_coef;
17136 static struct hda_codec_preset snd_hda_preset_realtek[] = {
17137 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17138 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17139 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17140 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17141 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17142 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17143 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17144 .patch = patch_alc861 },
17145 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17146 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17147 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17148 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17149 .patch = patch_alc883 },
17150 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17151 .patch = patch_alc662 },
17152 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17153 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17154 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17155 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
17156 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17157 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17158 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17159 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17160 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17161 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
17162 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17163 .patch = patch_alc883 },
17164 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
17165 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
17166 {} /* terminator */
17169 MODULE_ALIAS("snd-hda-codec-id:10ec*");
17171 MODULE_LICENSE("GPL");
17172 MODULE_DESCRIPTION("Realtek HD-audio codec");
17174 static struct hda_codec_preset_list realtek_list = {
17175 .preset = snd_hda_preset_realtek,
17176 .owner = THIS_MODULE,
17179 static int __init patch_realtek_init(void)
17181 return snd_hda_add_codec_preset(&realtek_list);
17184 static void __exit patch_realtek_exit(void)
17186 snd_hda_delete_codec_preset(&realtek_list);
17189 module_init(patch_realtek_init)
17190 module_exit(patch_realtek_exit)