2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include "hda_codec.h"
32 #include "hda_local.h"
34 #define ALC880_FRONT_EVENT 0x01
35 #define ALC880_DCVOL_EVENT 0x02
36 #define ALC880_HP_EVENT 0x04
37 #define ALC880_MIC_EVENT 0x08
39 /* ALC880 board config type */
62 #ifdef CONFIG_SND_DEBUG
66 ALC880_MODEL_LAST /* last tag */
78 #ifdef CONFIG_SND_DEBUG
82 ALC260_MODEL_LAST /* last tag */
92 ALC262_HP_BPC_D7000_WL,
93 ALC262_HP_BPC_D7000_WF,
101 ALC262_MODEL_LAST /* last tag */
111 #ifdef CONFIG_SND_DEBUG
115 ALC268_MODEL_LAST /* last tag */
122 ALC269_MODEL_LAST /* last tag */
139 /* ALC861-VD models */
160 ALC662_ASUS_EEEPC_P701,
161 ALC662_ASUS_EEEPC_EP20,
189 ALC883_TARGA_2ch_DIG,
195 ALC883_LENOVO_101E_2ch,
196 ALC883_LENOVO_NB0763,
197 ALC888_LENOVO_MS7195_DIG,
208 #define GPIO_MASK 0x03
211 /* codec parameterization */
212 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
213 unsigned int num_mixers;
215 const struct hda_verb *init_verbs[5]; /* initialization verbs
219 unsigned int num_init_verbs;
221 char *stream_name_analog; /* analog PCM stream */
222 struct hda_pcm_stream *stream_analog_playback;
223 struct hda_pcm_stream *stream_analog_capture;
224 struct hda_pcm_stream *stream_analog_alt_playback;
225 struct hda_pcm_stream *stream_analog_alt_capture;
227 char *stream_name_digital; /* digital PCM stream */
228 struct hda_pcm_stream *stream_digital_playback;
229 struct hda_pcm_stream *stream_digital_capture;
232 struct hda_multi_out multiout; /* playback set-up
233 * max_channels, dacs must be set
234 * dig_out_nid and hp_nid are optional
236 hda_nid_t alt_dac_nid;
239 unsigned int num_adc_nids;
241 hda_nid_t dig_in_nid; /* digital-in NID; optional */
244 unsigned int num_mux_defs;
245 const struct hda_input_mux *input_mux;
246 unsigned int cur_mux[3];
249 const struct hda_channel_mode *channel_mode;
250 int num_channel_mode;
253 /* PCM information */
254 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
256 /* dynamic controls, init_verbs and input_mux */
257 struct auto_pin_cfg autocfg;
258 unsigned int num_kctl_alloc, num_kctl_used;
259 struct snd_kcontrol_new *kctl_alloc;
260 struct hda_input_mux private_imux;
261 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
264 void (*init_hook)(struct hda_codec *codec);
265 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
267 /* for pin sensing */
268 unsigned int sense_updated: 1;
269 unsigned int jack_present: 1;
270 unsigned int master_sw: 1;
272 /* for virtual master */
273 hda_nid_t vmaster_nid;
275 #ifdef CONFIG_SND_HDA_POWER_SAVE
276 struct hda_loopback_check loopback;
281 * configuration template - to be copied to the spec instance
283 struct alc_config_preset {
284 struct snd_kcontrol_new *mixers[5]; /* should be identical size
287 const struct hda_verb *init_verbs[5];
288 unsigned int num_dacs;
290 hda_nid_t dig_out_nid; /* optional */
291 hda_nid_t hp_nid; /* optional */
292 unsigned int num_adc_nids;
294 hda_nid_t dig_in_nid;
295 unsigned int num_channel_mode;
296 const struct hda_channel_mode *channel_mode;
298 unsigned int num_mux_defs;
299 const struct hda_input_mux *input_mux;
300 void (*unsol_event)(struct hda_codec *, unsigned int);
301 void (*init_hook)(struct hda_codec *);
302 #ifdef CONFIG_SND_HDA_POWER_SAVE
303 struct hda_amp_list *loopbacks;
311 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
312 struct snd_ctl_elem_info *uinfo)
314 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
315 struct alc_spec *spec = codec->spec;
316 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
317 if (mux_idx >= spec->num_mux_defs)
319 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
322 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
323 struct snd_ctl_elem_value *ucontrol)
325 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
326 struct alc_spec *spec = codec->spec;
327 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
329 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
333 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
334 struct snd_ctl_elem_value *ucontrol)
336 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
337 struct alc_spec *spec = codec->spec;
338 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
339 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
340 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
341 spec->adc_nids[adc_idx],
342 &spec->cur_mux[adc_idx]);
347 * channel mode setting
349 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
350 struct snd_ctl_elem_info *uinfo)
352 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
353 struct alc_spec *spec = codec->spec;
354 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
355 spec->num_channel_mode);
358 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
359 struct snd_ctl_elem_value *ucontrol)
361 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
362 struct alc_spec *spec = codec->spec;
363 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
364 spec->num_channel_mode,
365 spec->multiout.max_channels);
368 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
369 struct snd_ctl_elem_value *ucontrol)
371 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
372 struct alc_spec *spec = codec->spec;
373 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
374 spec->num_channel_mode,
375 &spec->multiout.max_channels);
376 if (err >= 0 && spec->need_dac_fix)
377 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
382 * Control the mode of pin widget settings via the mixer. "pc" is used
383 * instead of "%" to avoid consequences of accidently treating the % as
384 * being part of a format specifier. Maximum allowed length of a value is
385 * 63 characters plus NULL terminator.
387 * Note: some retasking pin complexes seem to ignore requests for input
388 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
389 * are requested. Therefore order this list so that this behaviour will not
390 * cause problems when mixer clients move through the enum sequentially.
391 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
394 static char *alc_pin_mode_names[] = {
395 "Mic 50pc bias", "Mic 80pc bias",
396 "Line in", "Line out", "Headphone out",
398 static unsigned char alc_pin_mode_values[] = {
399 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
401 /* The control can present all 5 options, or it can limit the options based
402 * in the pin being assumed to be exclusively an input or an output pin. In
403 * addition, "input" pins may or may not process the mic bias option
404 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
405 * accept requests for bias as of chip versions up to March 2006) and/or
406 * wiring in the computer.
408 #define ALC_PIN_DIR_IN 0x00
409 #define ALC_PIN_DIR_OUT 0x01
410 #define ALC_PIN_DIR_INOUT 0x02
411 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
412 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
414 /* Info about the pin modes supported by the different pin direction modes.
415 * For each direction the minimum and maximum values are given.
417 static signed char alc_pin_mode_dir_info[5][2] = {
418 { 0, 2 }, /* ALC_PIN_DIR_IN */
419 { 3, 4 }, /* ALC_PIN_DIR_OUT */
420 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
421 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
422 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
424 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
425 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
426 #define alc_pin_mode_n_items(_dir) \
427 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
429 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
430 struct snd_ctl_elem_info *uinfo)
432 unsigned int item_num = uinfo->value.enumerated.item;
433 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
435 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
437 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
439 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
440 item_num = alc_pin_mode_min(dir);
441 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
445 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_value *ucontrol)
449 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
450 hda_nid_t nid = kcontrol->private_value & 0xffff;
451 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
452 long *valp = ucontrol->value.integer.value;
453 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
454 AC_VERB_GET_PIN_WIDGET_CONTROL,
457 /* Find enumerated value for current pinctl setting */
458 i = alc_pin_mode_min(dir);
459 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
461 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
465 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
466 struct snd_ctl_elem_value *ucontrol)
469 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
470 hda_nid_t nid = kcontrol->private_value & 0xffff;
471 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
472 long val = *ucontrol->value.integer.value;
473 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
474 AC_VERB_GET_PIN_WIDGET_CONTROL,
477 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
478 val = alc_pin_mode_min(dir);
480 change = pinctl != alc_pin_mode_values[val];
482 /* Set pin mode to that requested */
483 snd_hda_codec_write_cache(codec, nid, 0,
484 AC_VERB_SET_PIN_WIDGET_CONTROL,
485 alc_pin_mode_values[val]);
487 /* Also enable the retasking pin's input/output as required
488 * for the requested pin mode. Enum values of 2 or less are
491 * Dynamically switching the input/output buffers probably
492 * reduces noise slightly (particularly on input) so we'll
493 * do it. However, having both input and output buffers
494 * enabled simultaneously doesn't seem to be problematic if
495 * this turns out to be necessary in the future.
498 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
499 HDA_AMP_MUTE, HDA_AMP_MUTE);
500 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
503 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
504 HDA_AMP_MUTE, HDA_AMP_MUTE);
505 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
512 #define ALC_PIN_MODE(xname, nid, dir) \
513 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
514 .info = alc_pin_mode_info, \
515 .get = alc_pin_mode_get, \
516 .put = alc_pin_mode_put, \
517 .private_value = nid | (dir<<16) }
519 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
520 * together using a mask with more than one bit set. This control is
521 * currently used only by the ALC260 test model. At this stage they are not
522 * needed for any "production" models.
524 #ifdef CONFIG_SND_DEBUG
525 #define alc_gpio_data_info snd_ctl_boolean_mono_info
527 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
528 struct snd_ctl_elem_value *ucontrol)
530 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
531 hda_nid_t nid = kcontrol->private_value & 0xffff;
532 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
533 long *valp = ucontrol->value.integer.value;
534 unsigned int val = snd_hda_codec_read(codec, nid, 0,
535 AC_VERB_GET_GPIO_DATA, 0x00);
537 *valp = (val & mask) != 0;
540 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
541 struct snd_ctl_elem_value *ucontrol)
544 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
545 hda_nid_t nid = kcontrol->private_value & 0xffff;
546 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
547 long val = *ucontrol->value.integer.value;
548 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
549 AC_VERB_GET_GPIO_DATA,
552 /* Set/unset the masked GPIO bit(s) as needed */
553 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
558 snd_hda_codec_write_cache(codec, nid, 0,
559 AC_VERB_SET_GPIO_DATA, gpio_data);
563 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
564 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
565 .info = alc_gpio_data_info, \
566 .get = alc_gpio_data_get, \
567 .put = alc_gpio_data_put, \
568 .private_value = nid | (mask<<16) }
569 #endif /* CONFIG_SND_DEBUG */
571 /* A switch control to allow the enabling of the digital IO pins on the
572 * ALC260. This is incredibly simplistic; the intention of this control is
573 * to provide something in the test model allowing digital outputs to be
574 * identified if present. If models are found which can utilise these
575 * outputs a more complete mixer control can be devised for those models if
578 #ifdef CONFIG_SND_DEBUG
579 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
581 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
582 struct snd_ctl_elem_value *ucontrol)
584 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
585 hda_nid_t nid = kcontrol->private_value & 0xffff;
586 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
587 long *valp = ucontrol->value.integer.value;
588 unsigned int val = snd_hda_codec_read(codec, nid, 0,
589 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
591 *valp = (val & mask) != 0;
594 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
595 struct snd_ctl_elem_value *ucontrol)
598 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
599 hda_nid_t nid = kcontrol->private_value & 0xffff;
600 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
601 long val = *ucontrol->value.integer.value;
602 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
603 AC_VERB_GET_DIGI_CONVERT_1,
606 /* Set/unset the masked control bit(s) as needed */
607 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
612 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
617 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
618 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
619 .info = alc_spdif_ctrl_info, \
620 .get = alc_spdif_ctrl_get, \
621 .put = alc_spdif_ctrl_put, \
622 .private_value = nid | (mask<<16) }
623 #endif /* CONFIG_SND_DEBUG */
625 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
626 * Again, this is only used in the ALC26x test models to help identify when
627 * the EAPD line must be asserted for features to work.
629 #ifdef CONFIG_SND_DEBUG
630 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
632 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
633 struct snd_ctl_elem_value *ucontrol)
635 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
636 hda_nid_t nid = kcontrol->private_value & 0xffff;
637 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
638 long *valp = ucontrol->value.integer.value;
639 unsigned int val = snd_hda_codec_read(codec, nid, 0,
640 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
642 *valp = (val & mask) != 0;
646 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
647 struct snd_ctl_elem_value *ucontrol)
650 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
651 hda_nid_t nid = kcontrol->private_value & 0xffff;
652 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
653 long val = *ucontrol->value.integer.value;
654 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
655 AC_VERB_GET_EAPD_BTLENABLE,
658 /* Set/unset the masked control bit(s) as needed */
659 change = (!val ? 0 : mask) != (ctrl_data & mask);
664 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
670 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
671 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
672 .info = alc_eapd_ctrl_info, \
673 .get = alc_eapd_ctrl_get, \
674 .put = alc_eapd_ctrl_put, \
675 .private_value = nid | (mask<<16) }
676 #endif /* CONFIG_SND_DEBUG */
679 * set up from the preset table
681 static void setup_preset(struct alc_spec *spec,
682 const struct alc_config_preset *preset)
686 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
687 spec->mixers[spec->num_mixers++] = preset->mixers[i];
688 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
690 spec->init_verbs[spec->num_init_verbs++] =
691 preset->init_verbs[i];
693 spec->channel_mode = preset->channel_mode;
694 spec->num_channel_mode = preset->num_channel_mode;
695 spec->need_dac_fix = preset->need_dac_fix;
697 spec->multiout.max_channels = spec->channel_mode[0].channels;
699 spec->multiout.num_dacs = preset->num_dacs;
700 spec->multiout.dac_nids = preset->dac_nids;
701 spec->multiout.dig_out_nid = preset->dig_out_nid;
702 spec->multiout.hp_nid = preset->hp_nid;
704 spec->num_mux_defs = preset->num_mux_defs;
705 if (!spec->num_mux_defs)
706 spec->num_mux_defs = 1;
707 spec->input_mux = preset->input_mux;
709 spec->num_adc_nids = preset->num_adc_nids;
710 spec->adc_nids = preset->adc_nids;
711 spec->dig_in_nid = preset->dig_in_nid;
713 spec->unsol_event = preset->unsol_event;
714 spec->init_hook = preset->init_hook;
715 #ifdef CONFIG_SND_HDA_POWER_SAVE
716 spec->loopback.amplist = preset->loopbacks;
720 /* Enable GPIO mask and set output */
721 static struct hda_verb alc_gpio1_init_verbs[] = {
722 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
723 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
724 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
728 static struct hda_verb alc_gpio2_init_verbs[] = {
729 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
730 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
731 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
735 static struct hda_verb alc_gpio3_init_verbs[] = {
736 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
737 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
738 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
742 static void alc_sku_automute(struct hda_codec *codec)
744 struct alc_spec *spec = codec->spec;
746 unsigned int present;
747 unsigned int hp_nid = spec->autocfg.hp_pins[0];
748 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
750 /* need to execute and sync at first */
751 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
752 present = snd_hda_codec_read(codec, hp_nid, 0,
753 AC_VERB_GET_PIN_SENSE, 0);
754 spec->jack_present = (present & 0x80000000) != 0;
755 if (spec->jack_present) {
756 /* mute internal speaker */
757 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
758 HDA_AMP_MUTE, HDA_AMP_MUTE);
760 /* unmute internal speaker if necessary */
761 mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0);
762 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
767 /* unsolicited event for HP jack sensing */
768 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
770 if (codec->vendor_id == 0x10ec0880)
774 if (res != ALC880_HP_EVENT)
777 alc_sku_automute(codec);
780 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
781 * 31 ~ 16 : Manufacture ID
783 * 7 ~ 0 : Assembly ID
784 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
786 static void alc_subsystem_id(struct hda_codec *codec,
787 unsigned int porta, unsigned int porte,
790 unsigned int ass, tmp, i;
792 struct alc_spec *spec = codec->spec;
794 ass = codec->subsystem_id & 0xffff;
795 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
799 * 31~30 : port conetcivity
802 * 19~16 : Check sum (15:1)
807 if (codec->vendor_id == 0x10ec0260)
809 ass = snd_hda_codec_read(codec, nid, 0,
810 AC_VERB_GET_CONFIG_DEFAULT, 0);
811 if (!(ass & 1) && !(ass & 0x100000))
813 if ((ass >> 30) != 1) /* no physical connection */
818 for (i = 1; i < 16; i++) {
822 if (((ass >> 16) & 0xf) != tmp)
828 * 2 : 0 --> Desktop, 1 --> Laptop
829 * 3~5 : External Amplifier control
832 tmp = (ass & 0x38) >> 3; /* external Amp control */
835 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
838 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
841 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
843 case 5: /* set EAPD output high */
844 switch (codec->vendor_id) {
846 snd_hda_codec_write(codec, 0x0f, 0,
847 AC_VERB_SET_EAPD_BTLENABLE, 2);
848 snd_hda_codec_write(codec, 0x10, 0,
849 AC_VERB_SET_EAPD_BTLENABLE, 2);
857 snd_hda_codec_write(codec, 0x14, 0,
858 AC_VERB_SET_EAPD_BTLENABLE, 2);
859 snd_hda_codec_write(codec, 0x15, 0,
860 AC_VERB_SET_EAPD_BTLENABLE, 2);
863 switch (codec->vendor_id) {
865 snd_hda_codec_write(codec, 0x1a, 0,
866 AC_VERB_SET_COEF_INDEX, 7);
867 tmp = snd_hda_codec_read(codec, 0x1a, 0,
868 AC_VERB_GET_PROC_COEF, 0);
869 snd_hda_codec_write(codec, 0x1a, 0,
870 AC_VERB_SET_COEF_INDEX, 7);
871 snd_hda_codec_write(codec, 0x1a, 0,
872 AC_VERB_SET_PROC_COEF,
881 snd_hda_codec_write(codec, 0x20, 0,
882 AC_VERB_SET_COEF_INDEX, 7);
883 tmp = snd_hda_codec_read(codec, 0x20, 0,
884 AC_VERB_GET_PROC_COEF, 0);
885 snd_hda_codec_write(codec, 0x20, 0,
886 AC_VERB_SET_COEF_INDEX, 7);
887 snd_hda_codec_write(codec, 0x20, 0,
888 AC_VERB_SET_PROC_COEF,
893 snd_hda_codec_write(codec, 0x20, 0,
894 AC_VERB_SET_COEF_INDEX, 7);
895 tmp = snd_hda_codec_read(codec, 0x20, 0,
896 AC_VERB_GET_PROC_COEF, 0);
897 snd_hda_codec_write(codec, 0x20, 0,
898 AC_VERB_SET_COEF_INDEX, 7);
899 snd_hda_codec_write(codec, 0x20, 0,
900 AC_VERB_SET_PROC_COEF,
908 /* is laptop or Desktop and enable the function "Mute internal speaker
909 * when the external headphone out jack is plugged"
914 * 10~8 : Jack location
915 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
917 * 15 : 1 --> enable the function "Mute internal speaker
918 * when the external headphone out jack is plugged"
920 if (!spec->autocfg.speaker_pins[0]) {
921 if (spec->autocfg.line_out_pins[0])
922 spec->autocfg.speaker_pins[0] =
923 spec->autocfg.line_out_pins[0];
928 if (!spec->autocfg.hp_pins[0]) {
929 tmp = (ass >> 11) & 0x3; /* HP to chassis */
931 spec->autocfg.hp_pins[0] = porta;
933 spec->autocfg.hp_pins[0] = porte;
935 spec->autocfg.hp_pins[0] = portd;
940 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
941 AC_VERB_SET_UNSOLICITED_ENABLE,
942 AC_USRSP_EN | ALC880_HP_EVENT);
943 spec->unsol_event = alc_sku_unsol_event;
944 spec->init_hook = alc_sku_automute;
948 * Fix-up pin default configurations
956 static void alc_fix_pincfg(struct hda_codec *codec,
957 const struct snd_pci_quirk *quirk,
958 const struct alc_pincfg **pinfix)
960 const struct alc_pincfg *cfg;
962 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
966 cfg = pinfix[quirk->value];
967 for (; cfg->nid; cfg++) {
970 for (i = 0; i < 4; i++) {
971 snd_hda_codec_write(codec, cfg->nid, 0,
972 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
980 * ALC880 3-stack model
982 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
983 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
984 * F-Mic = 0x1b, HP = 0x19
987 static hda_nid_t alc880_dac_nids[4] = {
988 /* front, rear, clfe, rear_surr */
989 0x02, 0x05, 0x04, 0x03
992 static hda_nid_t alc880_adc_nids[3] = {
997 /* The datasheet says the node 0x07 is connected from inputs,
998 * but it shows zero connection in the real implementation on some devices.
999 * Note: this is a 915GAV bug, fixed on 915GLV
1001 static hda_nid_t alc880_adc_nids_alt[2] = {
1006 #define ALC880_DIGOUT_NID 0x06
1007 #define ALC880_DIGIN_NID 0x0a
1009 static struct hda_input_mux alc880_capture_source = {
1013 { "Front Mic", 0x3 },
1019 /* channel source setting (2/6 channel selection for 3-stack) */
1021 static struct hda_verb alc880_threestack_ch2_init[] = {
1022 /* set line-in to input, mute it */
1023 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1024 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1025 /* set mic-in to input vref 80%, mute it */
1026 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1027 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1032 static struct hda_verb alc880_threestack_ch6_init[] = {
1033 /* set line-in to output, unmute it */
1034 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1035 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1036 /* set mic-in to output, unmute it */
1037 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1038 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1042 static struct hda_channel_mode alc880_threestack_modes[2] = {
1043 { 2, alc880_threestack_ch2_init },
1044 { 6, alc880_threestack_ch6_init },
1047 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1048 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1049 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1050 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1051 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1052 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1053 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1054 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1055 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1056 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1057 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1058 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1059 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1060 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1061 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1062 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1063 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1064 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1065 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1066 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1068 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1069 .name = "Channel Mode",
1070 .info = alc_ch_mode_info,
1071 .get = alc_ch_mode_get,
1072 .put = alc_ch_mode_put,
1077 /* capture mixer elements */
1078 static struct snd_kcontrol_new alc880_capture_mixer[] = {
1079 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1080 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1081 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1082 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1083 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1084 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1086 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1087 /* The multiple "Capture Source" controls confuse alsamixer
1088 * So call somewhat different..
1090 /* .name = "Capture Source", */
1091 .name = "Input Source",
1093 .info = alc_mux_enum_info,
1094 .get = alc_mux_enum_get,
1095 .put = alc_mux_enum_put,
1100 /* capture mixer elements (in case NID 0x07 not available) */
1101 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1102 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1103 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1104 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1105 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1107 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1108 /* The multiple "Capture Source" controls confuse alsamixer
1109 * So call somewhat different..
1111 /* .name = "Capture Source", */
1112 .name = "Input Source",
1114 .info = alc_mux_enum_info,
1115 .get = alc_mux_enum_get,
1116 .put = alc_mux_enum_put,
1124 * ALC880 5-stack model
1126 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1128 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1129 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1132 /* additional mixers to alc880_three_stack_mixer */
1133 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1134 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1135 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1139 /* channel source setting (6/8 channel selection for 5-stack) */
1141 static struct hda_verb alc880_fivestack_ch6_init[] = {
1142 /* set line-in to input, mute it */
1143 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1144 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1149 static struct hda_verb alc880_fivestack_ch8_init[] = {
1150 /* set line-in to output, unmute it */
1151 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1152 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1156 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1157 { 6, alc880_fivestack_ch6_init },
1158 { 8, alc880_fivestack_ch8_init },
1163 * ALC880 6-stack model
1165 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1166 * Side = 0x05 (0x0f)
1167 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1168 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1171 static hda_nid_t alc880_6st_dac_nids[4] = {
1172 /* front, rear, clfe, rear_surr */
1173 0x02, 0x03, 0x04, 0x05
1176 static struct hda_input_mux alc880_6stack_capture_source = {
1180 { "Front Mic", 0x1 },
1186 /* fixed 8-channels */
1187 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1191 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1192 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1193 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1194 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1195 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1196 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1197 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1198 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1199 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1200 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1201 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1202 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1203 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1204 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1205 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1206 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1207 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1208 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1209 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1210 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1211 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1213 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1214 .name = "Channel Mode",
1215 .info = alc_ch_mode_info,
1216 .get = alc_ch_mode_get,
1217 .put = alc_ch_mode_put,
1226 * W810 has rear IO for:
1229 * Center/LFE (DAC 04)
1232 * The system also has a pair of internal speakers, and a headphone jack.
1233 * These are both connected to Line2 on the codec, hence to DAC 02.
1235 * There is a variable resistor to control the speaker or headphone
1236 * volume. This is a hardware-only device without a software API.
1238 * Plugging headphones in will disable the internal speakers. This is
1239 * implemented in hardware, not via the driver using jack sense. In
1240 * a similar fashion, plugging into the rear socket marked "front" will
1241 * disable both the speakers and headphones.
1243 * For input, there's a microphone jack, and an "audio in" jack.
1244 * These may not do anything useful with this driver yet, because I
1245 * haven't setup any initialization verbs for these yet...
1248 static hda_nid_t alc880_w810_dac_nids[3] = {
1249 /* front, rear/surround, clfe */
1253 /* fixed 6 channels */
1254 static struct hda_channel_mode alc880_w810_modes[1] = {
1258 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1259 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1260 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1261 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1262 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1263 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1264 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1265 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1266 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1267 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1268 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1276 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1277 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1281 static hda_nid_t alc880_z71v_dac_nids[1] = {
1284 #define ALC880_Z71V_HP_DAC 0x03
1286 /* fixed 2 channels */
1287 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1291 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1292 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1293 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1294 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1295 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1296 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1297 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1298 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1299 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1305 * ALC880 F1734 model
1307 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1308 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1311 static hda_nid_t alc880_f1734_dac_nids[1] = {
1314 #define ALC880_F1734_HP_DAC 0x02
1316 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1317 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1318 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1319 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1320 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1321 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1322 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1323 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1324 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1332 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1333 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1334 * Mic = 0x18, Line = 0x1a
1337 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1338 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1340 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1341 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1342 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1343 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1344 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1345 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1346 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1347 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1348 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1349 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1350 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1351 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1352 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1353 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1354 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1356 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1357 .name = "Channel Mode",
1358 .info = alc_ch_mode_info,
1359 .get = alc_ch_mode_get,
1360 .put = alc_ch_mode_put,
1366 * ALC880 ASUS W1V model
1368 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1369 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1370 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1373 /* additional mixers to alc880_asus_mixer */
1374 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1375 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1376 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1380 /* additional mixers to alc880_asus_mixer */
1381 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1382 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1383 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1388 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1389 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1390 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1391 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1392 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1393 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1394 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1395 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1396 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1397 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1399 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1400 /* The multiple "Capture Source" controls confuse alsamixer
1401 * So call somewhat different..
1403 /* .name = "Capture Source", */
1404 .name = "Input Source",
1406 .info = alc_mux_enum_info,
1407 .get = alc_mux_enum_get,
1408 .put = alc_mux_enum_put,
1414 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1415 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1416 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1417 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1418 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1419 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1420 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1421 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1422 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1423 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1424 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1425 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1426 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1427 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1428 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1429 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1430 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1431 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1432 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1434 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1435 .name = "Channel Mode",
1436 .info = alc_ch_mode_info,
1437 .get = alc_ch_mode_get,
1438 .put = alc_ch_mode_put,
1443 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1444 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1445 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1446 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1447 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1448 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1449 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1450 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1451 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1452 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1453 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1457 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1458 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1459 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1460 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1461 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1462 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1463 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1468 * virtual master controls
1472 * slave controls for virtual master
1474 static const char *alc_slave_vols[] = {
1475 "Front Playback Volume",
1476 "Surround Playback Volume",
1477 "Center Playback Volume",
1478 "LFE Playback Volume",
1479 "Side Playback Volume",
1480 "Headphone Playback Volume",
1481 "Speaker Playback Volume",
1482 "Mono Playback Volume",
1483 "Line-Out Playback Volume",
1487 static const char *alc_slave_sws[] = {
1488 "Front Playback Switch",
1489 "Surround Playback Switch",
1490 "Center Playback Switch",
1491 "LFE Playback Switch",
1492 "Side Playback Switch",
1493 "Headphone Playback Switch",
1494 "Speaker Playback Switch",
1495 "Mono Playback Switch",
1496 "IEC958 Playback Switch",
1501 * build control elements
1503 static int alc_build_controls(struct hda_codec *codec)
1505 struct alc_spec *spec = codec->spec;
1509 for (i = 0; i < spec->num_mixers; i++) {
1510 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1515 if (spec->multiout.dig_out_nid) {
1516 err = snd_hda_create_spdif_out_ctls(codec,
1517 spec->multiout.dig_out_nid);
1521 if (spec->dig_in_nid) {
1522 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1527 /* if we have no master control, let's create it */
1528 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1529 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1530 HDA_OUTPUT, spec->vmaster_tlv);
1531 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1532 spec->vmaster_tlv, alc_slave_vols);
1536 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1537 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1538 NULL, alc_slave_sws);
1548 * initialize the codec volumes, etc
1552 * generic initialization of ADC, input mixers and output mixers
1554 static struct hda_verb alc880_volume_init_verbs[] = {
1556 * Unmute ADC0-2 and set the default input to mic-in
1558 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1559 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1560 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1561 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1562 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1563 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1565 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1567 * Note: PASD motherboards uses the Line In 2 as the input for front
1570 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1571 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1572 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1573 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1574 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1575 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1576 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1577 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1580 * Set up output mixers (0x0c - 0x0f)
1582 /* set vol=0 to output mixers */
1583 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1584 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1585 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1586 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1587 /* set up input amps for analog loopback */
1588 /* Amp Indices: DAC = 0, mixer = 1 */
1589 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1590 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1591 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1592 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1593 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1594 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1595 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1596 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1602 * 3-stack pin configuration:
1603 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1605 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1607 * preset connection lists of input pins
1608 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1610 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1611 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1612 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1615 * Set pin mode and muting
1617 /* set front pin widgets 0x14 for output */
1618 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1619 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1620 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1621 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1622 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1623 /* Mic2 (as headphone out) for HP output */
1624 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1625 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1626 /* Line In pin widget for input */
1627 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1628 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1629 /* Line2 (as front mic) pin widget for input and vref at 80% */
1630 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1631 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1632 /* CD pin widget for input */
1633 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1639 * 5-stack pin configuration:
1640 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1641 * line-in/side = 0x1a, f-mic = 0x1b
1643 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1645 * preset connection lists of input pins
1646 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1648 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1649 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1652 * Set pin mode and muting
1654 /* set pin widgets 0x14-0x17 for output */
1655 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1656 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1657 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1658 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1659 /* unmute pins for output (no gain on this amp) */
1660 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1662 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1663 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1665 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1666 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1667 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1668 /* Mic2 (as headphone out) for HP output */
1669 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1670 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1671 /* Line In pin widget for input */
1672 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1673 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1674 /* Line2 (as front mic) pin widget for input and vref at 80% */
1675 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1676 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1677 /* CD pin widget for input */
1678 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1684 * W810 pin configuration:
1685 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1687 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1688 /* hphone/speaker input selector: front DAC */
1689 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1691 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1692 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1693 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1694 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1695 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1696 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1698 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1699 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1705 * Z71V pin configuration:
1706 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1708 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1709 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1710 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1711 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1712 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1714 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1715 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1716 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1717 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1723 * 6-stack pin configuration:
1724 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1725 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1727 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1728 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1730 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1731 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1732 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1733 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1734 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1735 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1736 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1737 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1739 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1740 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1741 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1742 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1743 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1744 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1745 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1746 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1747 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1753 * Uniwill pin configuration:
1754 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1757 static struct hda_verb alc880_uniwill_init_verbs[] = {
1758 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1760 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1761 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1762 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1764 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1765 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1766 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1767 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1768 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1769 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1770 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1771 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1772 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1773 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1775 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1776 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1777 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1778 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1779 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1780 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1781 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1782 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1783 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1785 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1786 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1793 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1795 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1796 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1798 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1799 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1800 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1801 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1802 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1803 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1804 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1805 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1807 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1808 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1809 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1811 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1812 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1813 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1814 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1815 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1816 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1818 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1819 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1824 static struct hda_verb alc880_beep_init_verbs[] = {
1825 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1829 /* toggle speaker-output according to the hp-jack state */
1830 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1832 unsigned int present;
1835 present = snd_hda_codec_read(codec, 0x14, 0,
1836 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1837 bits = present ? HDA_AMP_MUTE : 0;
1838 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1839 HDA_AMP_MUTE, bits);
1840 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1841 HDA_AMP_MUTE, bits);
1844 /* auto-toggle front mic */
1845 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1847 unsigned int present;
1850 present = snd_hda_codec_read(codec, 0x18, 0,
1851 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1852 bits = present ? HDA_AMP_MUTE : 0;
1853 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1856 static void alc880_uniwill_automute(struct hda_codec *codec)
1858 alc880_uniwill_hp_automute(codec);
1859 alc880_uniwill_mic_automute(codec);
1862 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1865 /* Looks like the unsol event is incompatible with the standard
1866 * definition. 4bit tag is placed at 28 bit!
1868 switch (res >> 28) {
1869 case ALC880_HP_EVENT:
1870 alc880_uniwill_hp_automute(codec);
1872 case ALC880_MIC_EVENT:
1873 alc880_uniwill_mic_automute(codec);
1878 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1880 unsigned int present;
1883 present = snd_hda_codec_read(codec, 0x14, 0,
1884 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1885 bits = present ? HDA_AMP_MUTE : 0;
1886 snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1889 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1891 unsigned int present;
1893 present = snd_hda_codec_read(codec, 0x21, 0,
1894 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1895 present &= HDA_AMP_VOLMASK;
1896 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1897 HDA_AMP_VOLMASK, present);
1898 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1899 HDA_AMP_VOLMASK, present);
1902 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1905 /* Looks like the unsol event is incompatible with the standard
1906 * definition. 4bit tag is placed at 28 bit!
1908 if ((res >> 28) == ALC880_HP_EVENT)
1909 alc880_uniwill_p53_hp_automute(codec);
1910 if ((res >> 28) == ALC880_DCVOL_EVENT)
1911 alc880_uniwill_p53_dcvol_automute(codec);
1915 * F1734 pin configuration:
1916 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1918 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1919 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1920 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1921 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1922 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1924 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1925 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1926 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1927 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1929 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1930 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1931 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1932 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1933 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1934 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1935 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1936 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1937 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1943 * ASUS pin configuration:
1944 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1946 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1947 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1948 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1949 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1950 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1952 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1953 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1954 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1955 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1956 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1957 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1958 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1959 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1961 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1962 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1963 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1964 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1965 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1966 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1967 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1968 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1969 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1974 /* Enable GPIO mask and set output */
1975 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1976 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1978 /* Clevo m520g init */
1979 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1980 /* headphone output */
1981 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1983 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1984 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1986 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1987 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1989 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1990 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1991 /* Mic1 (rear panel) */
1992 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1993 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1994 /* Mic2 (front panel) */
1995 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1996 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1998 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1999 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2000 /* change to EAPD mode */
2001 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2002 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2007 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2008 /* change to EAPD mode */
2009 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2010 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2012 /* Headphone output */
2013 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2015 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2016 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2018 /* Line In pin widget for input */
2019 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2020 /* CD pin widget for input */
2021 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2022 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2023 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2025 /* change to EAPD mode */
2026 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2027 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2033 * LG m1 express dual
2036 * Rear Line-In/Out (blue): 0x14
2037 * Build-in Mic-In: 0x15
2039 * HP-Out (green): 0x1b
2040 * Mic-In/Out (red): 0x19
2044 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2045 static hda_nid_t alc880_lg_dac_nids[3] = {
2049 /* seems analog CD is not working */
2050 static struct hda_input_mux alc880_lg_capture_source = {
2055 { "Internal Mic", 0x6 },
2059 /* 2,4,6 channel modes */
2060 static struct hda_verb alc880_lg_ch2_init[] = {
2061 /* set line-in and mic-in to input */
2062 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2063 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2067 static struct hda_verb alc880_lg_ch4_init[] = {
2068 /* set line-in to out and mic-in to input */
2069 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2070 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2074 static struct hda_verb alc880_lg_ch6_init[] = {
2075 /* set line-in and mic-in to output */
2076 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2077 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2081 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2082 { 2, alc880_lg_ch2_init },
2083 { 4, alc880_lg_ch4_init },
2084 { 6, alc880_lg_ch6_init },
2087 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2088 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2089 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2090 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2091 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2092 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2093 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2094 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2095 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2096 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2097 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2098 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2099 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2100 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2101 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2103 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2104 .name = "Channel Mode",
2105 .info = alc_ch_mode_info,
2106 .get = alc_ch_mode_get,
2107 .put = alc_ch_mode_put,
2112 static struct hda_verb alc880_lg_init_verbs[] = {
2113 /* set capture source to mic-in */
2114 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2115 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2116 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2117 /* mute all amp mixer inputs */
2118 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2119 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2120 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2121 /* line-in to input */
2122 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2123 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2125 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2126 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2128 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2129 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2130 /* mic-in to input */
2131 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2132 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2133 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2135 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2136 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2137 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2139 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2143 /* toggle speaker-output according to the hp-jack state */
2144 static void alc880_lg_automute(struct hda_codec *codec)
2146 unsigned int present;
2149 present = snd_hda_codec_read(codec, 0x1b, 0,
2150 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2151 bits = present ? HDA_AMP_MUTE : 0;
2152 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2153 HDA_AMP_MUTE, bits);
2156 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2158 /* Looks like the unsol event is incompatible with the standard
2159 * definition. 4bit tag is placed at 28 bit!
2161 if ((res >> 28) == 0x01)
2162 alc880_lg_automute(codec);
2171 * Built-in Mic-In: 0x19
2177 static struct hda_input_mux alc880_lg_lw_capture_source = {
2181 { "Internal Mic", 0x1 },
2186 #define alc880_lg_lw_modes alc880_threestack_modes
2188 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2189 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2190 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2191 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2192 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2193 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2194 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2195 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2196 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2197 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2198 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2199 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2200 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2201 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2202 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2204 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2205 .name = "Channel Mode",
2206 .info = alc_ch_mode_info,
2207 .get = alc_ch_mode_get,
2208 .put = alc_ch_mode_put,
2213 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2214 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2215 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2216 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2218 /* set capture source to mic-in */
2219 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2220 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2221 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2222 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2224 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2225 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2227 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2228 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2229 /* mic-in to input */
2230 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2231 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2233 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2234 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2236 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2240 /* toggle speaker-output according to the hp-jack state */
2241 static void alc880_lg_lw_automute(struct hda_codec *codec)
2243 unsigned int present;
2246 present = snd_hda_codec_read(codec, 0x1b, 0,
2247 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2248 bits = present ? HDA_AMP_MUTE : 0;
2249 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2250 HDA_AMP_MUTE, bits);
2253 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2255 /* Looks like the unsol event is incompatible with the standard
2256 * definition. 4bit tag is placed at 28 bit!
2258 if ((res >> 28) == 0x01)
2259 alc880_lg_lw_automute(codec);
2262 #ifdef CONFIG_SND_HDA_POWER_SAVE
2263 static struct hda_amp_list alc880_loopbacks[] = {
2264 { 0x0b, HDA_INPUT, 0 },
2265 { 0x0b, HDA_INPUT, 1 },
2266 { 0x0b, HDA_INPUT, 2 },
2267 { 0x0b, HDA_INPUT, 3 },
2268 { 0x0b, HDA_INPUT, 4 },
2272 static struct hda_amp_list alc880_lg_loopbacks[] = {
2273 { 0x0b, HDA_INPUT, 1 },
2274 { 0x0b, HDA_INPUT, 6 },
2275 { 0x0b, HDA_INPUT, 7 },
2284 static int alc_init(struct hda_codec *codec)
2286 struct alc_spec *spec = codec->spec;
2289 for (i = 0; i < spec->num_init_verbs; i++)
2290 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2292 if (spec->init_hook)
2293 spec->init_hook(codec);
2298 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2300 struct alc_spec *spec = codec->spec;
2302 if (spec->unsol_event)
2303 spec->unsol_event(codec, res);
2306 #ifdef CONFIG_SND_HDA_POWER_SAVE
2307 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2309 struct alc_spec *spec = codec->spec;
2310 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2315 * Analog playback callbacks
2317 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2318 struct hda_codec *codec,
2319 struct snd_pcm_substream *substream)
2321 struct alc_spec *spec = codec->spec;
2322 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2325 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2326 struct hda_codec *codec,
2327 unsigned int stream_tag,
2328 unsigned int format,
2329 struct snd_pcm_substream *substream)
2331 struct alc_spec *spec = codec->spec;
2332 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2333 stream_tag, format, substream);
2336 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2337 struct hda_codec *codec,
2338 struct snd_pcm_substream *substream)
2340 struct alc_spec *spec = codec->spec;
2341 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2347 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2348 struct hda_codec *codec,
2349 struct snd_pcm_substream *substream)
2351 struct alc_spec *spec = codec->spec;
2352 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2355 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2356 struct hda_codec *codec,
2357 unsigned int stream_tag,
2358 unsigned int format,
2359 struct snd_pcm_substream *substream)
2361 struct alc_spec *spec = codec->spec;
2362 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2363 stream_tag, format, substream);
2366 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2367 struct hda_codec *codec,
2368 struct snd_pcm_substream *substream)
2370 struct alc_spec *spec = codec->spec;
2371 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2377 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2378 struct hda_codec *codec,
2379 unsigned int stream_tag,
2380 unsigned int format,
2381 struct snd_pcm_substream *substream)
2383 struct alc_spec *spec = codec->spec;
2385 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2386 stream_tag, 0, format);
2390 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2391 struct hda_codec *codec,
2392 struct snd_pcm_substream *substream)
2394 struct alc_spec *spec = codec->spec;
2396 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2404 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2408 /* NID is set in alc_build_pcms */
2410 .open = alc880_playback_pcm_open,
2411 .prepare = alc880_playback_pcm_prepare,
2412 .cleanup = alc880_playback_pcm_cleanup
2416 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2420 /* NID is set in alc_build_pcms */
2423 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2427 /* NID is set in alc_build_pcms */
2430 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2431 .substreams = 2, /* can be overridden */
2434 /* NID is set in alc_build_pcms */
2436 .prepare = alc880_alt_capture_pcm_prepare,
2437 .cleanup = alc880_alt_capture_pcm_cleanup
2441 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2445 /* NID is set in alc_build_pcms */
2447 .open = alc880_dig_playback_pcm_open,
2448 .close = alc880_dig_playback_pcm_close,
2449 .prepare = alc880_dig_playback_pcm_prepare
2453 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2457 /* NID is set in alc_build_pcms */
2460 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2461 static struct hda_pcm_stream alc_pcm_null_stream = {
2467 static int alc_build_pcms(struct hda_codec *codec)
2469 struct alc_spec *spec = codec->spec;
2470 struct hda_pcm *info = spec->pcm_rec;
2473 codec->num_pcms = 1;
2474 codec->pcm_info = info;
2476 info->name = spec->stream_name_analog;
2477 if (spec->stream_analog_playback) {
2478 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2479 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2480 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2482 if (spec->stream_analog_capture) {
2483 snd_assert(spec->adc_nids, return -EINVAL);
2484 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2485 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2488 if (spec->channel_mode) {
2489 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2490 for (i = 0; i < spec->num_channel_mode; i++) {
2491 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2492 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2497 /* SPDIF for stream index #1 */
2498 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2499 codec->num_pcms = 2;
2500 info = spec->pcm_rec + 1;
2501 info->name = spec->stream_name_digital;
2502 info->pcm_type = HDA_PCM_TYPE_SPDIF;
2503 if (spec->multiout.dig_out_nid &&
2504 spec->stream_digital_playback) {
2505 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2506 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2508 if (spec->dig_in_nid &&
2509 spec->stream_digital_capture) {
2510 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2511 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2515 /* If the use of more than one ADC is requested for the current
2516 * model, configure a second analog capture-only PCM.
2518 /* Additional Analaog capture for index #2 */
2519 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2520 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2521 codec->num_pcms = 3;
2522 info = spec->pcm_rec + 2;
2523 info->name = spec->stream_name_analog;
2524 if (spec->alt_dac_nid) {
2525 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2526 *spec->stream_analog_alt_playback;
2527 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2530 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2531 alc_pcm_null_stream;
2532 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2534 if (spec->num_adc_nids > 1) {
2535 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2536 *spec->stream_analog_alt_capture;
2537 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2539 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2540 spec->num_adc_nids - 1;
2542 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2543 alc_pcm_null_stream;
2544 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2551 static void alc_free(struct hda_codec *codec)
2553 struct alc_spec *spec = codec->spec;
2559 if (spec->kctl_alloc) {
2560 for (i = 0; i < spec->num_kctl_used; i++)
2561 kfree(spec->kctl_alloc[i].name);
2562 kfree(spec->kctl_alloc);
2569 static struct hda_codec_ops alc_patch_ops = {
2570 .build_controls = alc_build_controls,
2571 .build_pcms = alc_build_pcms,
2574 .unsol_event = alc_unsol_event,
2575 #ifdef CONFIG_SND_HDA_POWER_SAVE
2576 .check_power_status = alc_check_power_status,
2582 * Test configuration for debugging
2584 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2587 #ifdef CONFIG_SND_DEBUG
2588 static hda_nid_t alc880_test_dac_nids[4] = {
2589 0x02, 0x03, 0x04, 0x05
2592 static struct hda_input_mux alc880_test_capture_source = {
2601 { "Surround", 0x6 },
2605 static struct hda_channel_mode alc880_test_modes[4] = {
2612 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2613 struct snd_ctl_elem_info *uinfo)
2615 static char *texts[] = {
2616 "N/A", "Line Out", "HP Out",
2617 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2619 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2621 uinfo->value.enumerated.items = 8;
2622 if (uinfo->value.enumerated.item >= 8)
2623 uinfo->value.enumerated.item = 7;
2624 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2628 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2629 struct snd_ctl_elem_value *ucontrol)
2631 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2632 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2633 unsigned int pin_ctl, item = 0;
2635 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2636 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2637 if (pin_ctl & AC_PINCTL_OUT_EN) {
2638 if (pin_ctl & AC_PINCTL_HP_EN)
2642 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2643 switch (pin_ctl & AC_PINCTL_VREFEN) {
2644 case AC_PINCTL_VREF_HIZ: item = 3; break;
2645 case AC_PINCTL_VREF_50: item = 4; break;
2646 case AC_PINCTL_VREF_GRD: item = 5; break;
2647 case AC_PINCTL_VREF_80: item = 6; break;
2648 case AC_PINCTL_VREF_100: item = 7; break;
2651 ucontrol->value.enumerated.item[0] = item;
2655 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2656 struct snd_ctl_elem_value *ucontrol)
2658 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2659 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2660 static unsigned int ctls[] = {
2661 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2662 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2663 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2664 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2665 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2666 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2668 unsigned int old_ctl, new_ctl;
2670 old_ctl = snd_hda_codec_read(codec, nid, 0,
2671 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2672 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2673 if (old_ctl != new_ctl) {
2675 snd_hda_codec_write_cache(codec, nid, 0,
2676 AC_VERB_SET_PIN_WIDGET_CONTROL,
2678 val = ucontrol->value.enumerated.item[0] >= 3 ?
2680 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2687 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2688 struct snd_ctl_elem_info *uinfo)
2690 static char *texts[] = {
2691 "Front", "Surround", "CLFE", "Side"
2693 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2695 uinfo->value.enumerated.items = 4;
2696 if (uinfo->value.enumerated.item >= 4)
2697 uinfo->value.enumerated.item = 3;
2698 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2702 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2703 struct snd_ctl_elem_value *ucontrol)
2705 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2706 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2709 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2710 ucontrol->value.enumerated.item[0] = sel & 3;
2714 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2715 struct snd_ctl_elem_value *ucontrol)
2717 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2718 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2721 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2722 if (ucontrol->value.enumerated.item[0] != sel) {
2723 sel = ucontrol->value.enumerated.item[0] & 3;
2724 snd_hda_codec_write_cache(codec, nid, 0,
2725 AC_VERB_SET_CONNECT_SEL, sel);
2731 #define PIN_CTL_TEST(xname,nid) { \
2732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2734 .info = alc_test_pin_ctl_info, \
2735 .get = alc_test_pin_ctl_get, \
2736 .put = alc_test_pin_ctl_put, \
2737 .private_value = nid \
2740 #define PIN_SRC_TEST(xname,nid) { \
2741 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2743 .info = alc_test_pin_src_info, \
2744 .get = alc_test_pin_src_get, \
2745 .put = alc_test_pin_src_put, \
2746 .private_value = nid \
2749 static struct snd_kcontrol_new alc880_test_mixer[] = {
2750 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2751 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2752 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2753 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2754 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2755 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2756 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2757 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2758 PIN_CTL_TEST("Front Pin Mode", 0x14),
2759 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2760 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2761 PIN_CTL_TEST("Side Pin Mode", 0x17),
2762 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2763 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2764 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2765 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2766 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2767 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2768 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2769 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2770 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2771 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2772 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2773 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2774 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2775 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2776 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2777 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2778 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2779 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2781 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2782 .name = "Channel Mode",
2783 .info = alc_ch_mode_info,
2784 .get = alc_ch_mode_get,
2785 .put = alc_ch_mode_put,
2790 static struct hda_verb alc880_test_init_verbs[] = {
2791 /* Unmute inputs of 0x0c - 0x0f */
2792 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2793 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2794 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2795 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2796 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2797 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2798 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2799 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2800 /* Vol output for 0x0c-0x0f */
2801 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2802 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2803 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2804 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2805 /* Set output pins 0x14-0x17 */
2806 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2807 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2808 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2809 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2810 /* Unmute output pins 0x14-0x17 */
2811 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2812 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2813 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2814 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2815 /* Set input pins 0x18-0x1c */
2816 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2817 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2818 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2819 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2820 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2821 /* Mute input pins 0x18-0x1b */
2822 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2823 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2824 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2825 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2827 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2828 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2829 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2830 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2831 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2832 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2833 /* Analog input/passthru */
2834 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2835 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2836 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2837 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2846 static const char *alc880_models[ALC880_MODEL_LAST] = {
2847 [ALC880_3ST] = "3stack",
2848 [ALC880_TCL_S700] = "tcl",
2849 [ALC880_3ST_DIG] = "3stack-digout",
2850 [ALC880_CLEVO] = "clevo",
2851 [ALC880_5ST] = "5stack",
2852 [ALC880_5ST_DIG] = "5stack-digout",
2853 [ALC880_W810] = "w810",
2854 [ALC880_Z71V] = "z71v",
2855 [ALC880_6ST] = "6stack",
2856 [ALC880_6ST_DIG] = "6stack-digout",
2857 [ALC880_ASUS] = "asus",
2858 [ALC880_ASUS_W1V] = "asus-w1v",
2859 [ALC880_ASUS_DIG] = "asus-dig",
2860 [ALC880_ASUS_DIG2] = "asus-dig2",
2861 [ALC880_UNIWILL_DIG] = "uniwill",
2862 [ALC880_UNIWILL_P53] = "uniwill-p53",
2863 [ALC880_FUJITSU] = "fujitsu",
2864 [ALC880_F1734] = "F1734",
2866 [ALC880_LG_LW] = "lg-lw",
2867 #ifdef CONFIG_SND_DEBUG
2868 [ALC880_TEST] = "test",
2870 [ALC880_AUTO] = "auto",
2873 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2874 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2875 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2876 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2877 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2878 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2879 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2880 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2881 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2882 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2883 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2884 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2885 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2886 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2887 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2888 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2889 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2890 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2891 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2892 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2893 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2894 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2895 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2896 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2897 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2898 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2899 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
2900 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2901 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2902 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2903 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2904 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2905 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2906 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2907 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2908 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2909 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2910 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2911 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2912 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2913 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2914 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2915 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2916 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2917 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2918 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2919 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2920 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2921 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2922 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2923 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2924 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2925 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2926 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2927 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2928 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
2929 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2930 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2931 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2932 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2933 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2934 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2935 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2936 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2937 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2938 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2939 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2940 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
2941 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2942 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2947 * ALC880 codec presets
2949 static struct alc_config_preset alc880_presets[] = {
2951 .mixers = { alc880_three_stack_mixer },
2952 .init_verbs = { alc880_volume_init_verbs,
2953 alc880_pin_3stack_init_verbs },
2954 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2955 .dac_nids = alc880_dac_nids,
2956 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2957 .channel_mode = alc880_threestack_modes,
2959 .input_mux = &alc880_capture_source,
2961 [ALC880_3ST_DIG] = {
2962 .mixers = { alc880_three_stack_mixer },
2963 .init_verbs = { alc880_volume_init_verbs,
2964 alc880_pin_3stack_init_verbs },
2965 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2966 .dac_nids = alc880_dac_nids,
2967 .dig_out_nid = ALC880_DIGOUT_NID,
2968 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2969 .channel_mode = alc880_threestack_modes,
2971 .input_mux = &alc880_capture_source,
2973 [ALC880_TCL_S700] = {
2974 .mixers = { alc880_tcl_s700_mixer },
2975 .init_verbs = { alc880_volume_init_verbs,
2976 alc880_pin_tcl_S700_init_verbs,
2977 alc880_gpio2_init_verbs },
2978 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2979 .dac_nids = alc880_dac_nids,
2981 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2982 .channel_mode = alc880_2_jack_modes,
2983 .input_mux = &alc880_capture_source,
2986 .mixers = { alc880_three_stack_mixer,
2987 alc880_five_stack_mixer},
2988 .init_verbs = { alc880_volume_init_verbs,
2989 alc880_pin_5stack_init_verbs },
2990 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2991 .dac_nids = alc880_dac_nids,
2992 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2993 .channel_mode = alc880_fivestack_modes,
2994 .input_mux = &alc880_capture_source,
2996 [ALC880_5ST_DIG] = {
2997 .mixers = { alc880_three_stack_mixer,
2998 alc880_five_stack_mixer },
2999 .init_verbs = { alc880_volume_init_verbs,
3000 alc880_pin_5stack_init_verbs },
3001 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3002 .dac_nids = alc880_dac_nids,
3003 .dig_out_nid = ALC880_DIGOUT_NID,
3004 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3005 .channel_mode = alc880_fivestack_modes,
3006 .input_mux = &alc880_capture_source,
3009 .mixers = { alc880_six_stack_mixer },
3010 .init_verbs = { alc880_volume_init_verbs,
3011 alc880_pin_6stack_init_verbs },
3012 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3013 .dac_nids = alc880_6st_dac_nids,
3014 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3015 .channel_mode = alc880_sixstack_modes,
3016 .input_mux = &alc880_6stack_capture_source,
3018 [ALC880_6ST_DIG] = {
3019 .mixers = { alc880_six_stack_mixer },
3020 .init_verbs = { alc880_volume_init_verbs,
3021 alc880_pin_6stack_init_verbs },
3022 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3023 .dac_nids = alc880_6st_dac_nids,
3024 .dig_out_nid = ALC880_DIGOUT_NID,
3025 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3026 .channel_mode = alc880_sixstack_modes,
3027 .input_mux = &alc880_6stack_capture_source,
3030 .mixers = { alc880_w810_base_mixer },
3031 .init_verbs = { alc880_volume_init_verbs,
3032 alc880_pin_w810_init_verbs,
3033 alc880_gpio2_init_verbs },
3034 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3035 .dac_nids = alc880_w810_dac_nids,
3036 .dig_out_nid = ALC880_DIGOUT_NID,
3037 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3038 .channel_mode = alc880_w810_modes,
3039 .input_mux = &alc880_capture_source,
3042 .mixers = { alc880_z71v_mixer },
3043 .init_verbs = { alc880_volume_init_verbs,
3044 alc880_pin_z71v_init_verbs },
3045 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3046 .dac_nids = alc880_z71v_dac_nids,
3047 .dig_out_nid = ALC880_DIGOUT_NID,
3049 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3050 .channel_mode = alc880_2_jack_modes,
3051 .input_mux = &alc880_capture_source,
3054 .mixers = { alc880_f1734_mixer },
3055 .init_verbs = { alc880_volume_init_verbs,
3056 alc880_pin_f1734_init_verbs },
3057 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3058 .dac_nids = alc880_f1734_dac_nids,
3060 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3061 .channel_mode = alc880_2_jack_modes,
3062 .input_mux = &alc880_capture_source,
3065 .mixers = { alc880_asus_mixer },
3066 .init_verbs = { alc880_volume_init_verbs,
3067 alc880_pin_asus_init_verbs,
3068 alc880_gpio1_init_verbs },
3069 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3070 .dac_nids = alc880_asus_dac_nids,
3071 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3072 .channel_mode = alc880_asus_modes,
3074 .input_mux = &alc880_capture_source,
3076 [ALC880_ASUS_DIG] = {
3077 .mixers = { alc880_asus_mixer },
3078 .init_verbs = { alc880_volume_init_verbs,
3079 alc880_pin_asus_init_verbs,
3080 alc880_gpio1_init_verbs },
3081 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3082 .dac_nids = alc880_asus_dac_nids,
3083 .dig_out_nid = ALC880_DIGOUT_NID,
3084 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3085 .channel_mode = alc880_asus_modes,
3087 .input_mux = &alc880_capture_source,
3089 [ALC880_ASUS_DIG2] = {
3090 .mixers = { alc880_asus_mixer },
3091 .init_verbs = { alc880_volume_init_verbs,
3092 alc880_pin_asus_init_verbs,
3093 alc880_gpio2_init_verbs }, /* use GPIO2 */
3094 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3095 .dac_nids = alc880_asus_dac_nids,
3096 .dig_out_nid = ALC880_DIGOUT_NID,
3097 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3098 .channel_mode = alc880_asus_modes,
3100 .input_mux = &alc880_capture_source,
3102 [ALC880_ASUS_W1V] = {
3103 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3104 .init_verbs = { alc880_volume_init_verbs,
3105 alc880_pin_asus_init_verbs,
3106 alc880_gpio1_init_verbs },
3107 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3108 .dac_nids = alc880_asus_dac_nids,
3109 .dig_out_nid = ALC880_DIGOUT_NID,
3110 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3111 .channel_mode = alc880_asus_modes,
3113 .input_mux = &alc880_capture_source,
3115 [ALC880_UNIWILL_DIG] = {
3116 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3117 .init_verbs = { alc880_volume_init_verbs,
3118 alc880_pin_asus_init_verbs },
3119 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3120 .dac_nids = alc880_asus_dac_nids,
3121 .dig_out_nid = ALC880_DIGOUT_NID,
3122 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3123 .channel_mode = alc880_asus_modes,
3125 .input_mux = &alc880_capture_source,
3127 [ALC880_UNIWILL] = {
3128 .mixers = { alc880_uniwill_mixer },
3129 .init_verbs = { alc880_volume_init_verbs,
3130 alc880_uniwill_init_verbs },
3131 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3132 .dac_nids = alc880_asus_dac_nids,
3133 .dig_out_nid = ALC880_DIGOUT_NID,
3134 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3135 .channel_mode = alc880_threestack_modes,
3137 .input_mux = &alc880_capture_source,
3138 .unsol_event = alc880_uniwill_unsol_event,
3139 .init_hook = alc880_uniwill_automute,
3141 [ALC880_UNIWILL_P53] = {
3142 .mixers = { alc880_uniwill_p53_mixer },
3143 .init_verbs = { alc880_volume_init_verbs,
3144 alc880_uniwill_p53_init_verbs },
3145 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3146 .dac_nids = alc880_asus_dac_nids,
3147 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3148 .channel_mode = alc880_threestack_modes,
3149 .input_mux = &alc880_capture_source,
3150 .unsol_event = alc880_uniwill_p53_unsol_event,
3151 .init_hook = alc880_uniwill_p53_hp_automute,
3153 [ALC880_FUJITSU] = {
3154 .mixers = { alc880_fujitsu_mixer,
3155 alc880_pcbeep_mixer, },
3156 .init_verbs = { alc880_volume_init_verbs,
3157 alc880_uniwill_p53_init_verbs,
3158 alc880_beep_init_verbs },
3159 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3160 .dac_nids = alc880_dac_nids,
3161 .dig_out_nid = ALC880_DIGOUT_NID,
3162 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3163 .channel_mode = alc880_2_jack_modes,
3164 .input_mux = &alc880_capture_source,
3165 .unsol_event = alc880_uniwill_p53_unsol_event,
3166 .init_hook = alc880_uniwill_p53_hp_automute,
3169 .mixers = { alc880_three_stack_mixer },
3170 .init_verbs = { alc880_volume_init_verbs,
3171 alc880_pin_clevo_init_verbs },
3172 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3173 .dac_nids = alc880_dac_nids,
3175 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3176 .channel_mode = alc880_threestack_modes,
3178 .input_mux = &alc880_capture_source,
3181 .mixers = { alc880_lg_mixer },
3182 .init_verbs = { alc880_volume_init_verbs,
3183 alc880_lg_init_verbs },
3184 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3185 .dac_nids = alc880_lg_dac_nids,
3186 .dig_out_nid = ALC880_DIGOUT_NID,
3187 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3188 .channel_mode = alc880_lg_ch_modes,
3190 .input_mux = &alc880_lg_capture_source,
3191 .unsol_event = alc880_lg_unsol_event,
3192 .init_hook = alc880_lg_automute,
3193 #ifdef CONFIG_SND_HDA_POWER_SAVE
3194 .loopbacks = alc880_lg_loopbacks,
3198 .mixers = { alc880_lg_lw_mixer },
3199 .init_verbs = { alc880_volume_init_verbs,
3200 alc880_lg_lw_init_verbs },
3201 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3202 .dac_nids = alc880_dac_nids,
3203 .dig_out_nid = ALC880_DIGOUT_NID,
3204 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3205 .channel_mode = alc880_lg_lw_modes,
3206 .input_mux = &alc880_lg_lw_capture_source,
3207 .unsol_event = alc880_lg_lw_unsol_event,
3208 .init_hook = alc880_lg_lw_automute,
3210 #ifdef CONFIG_SND_DEBUG
3212 .mixers = { alc880_test_mixer },
3213 .init_verbs = { alc880_test_init_verbs },
3214 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3215 .dac_nids = alc880_test_dac_nids,
3216 .dig_out_nid = ALC880_DIGOUT_NID,
3217 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3218 .channel_mode = alc880_test_modes,
3219 .input_mux = &alc880_test_capture_source,
3225 * Automatic parse of I/O pins from the BIOS configuration
3228 #define NUM_CONTROL_ALLOC 32
3229 #define NUM_VERB_ALLOC 32
3233 ALC_CTL_WIDGET_MUTE,
3236 static struct snd_kcontrol_new alc880_control_templates[] = {
3237 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3238 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3239 HDA_BIND_MUTE(NULL, 0, 0, 0),
3242 /* add dynamic controls */
3243 static int add_control(struct alc_spec *spec, int type, const char *name,
3246 struct snd_kcontrol_new *knew;
3248 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3249 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3251 /* array + terminator */
3252 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3255 if (spec->kctl_alloc) {
3256 memcpy(knew, spec->kctl_alloc,
3257 sizeof(*knew) * spec->num_kctl_alloc);
3258 kfree(spec->kctl_alloc);
3260 spec->kctl_alloc = knew;
3261 spec->num_kctl_alloc = num;
3264 knew = &spec->kctl_alloc[spec->num_kctl_used];
3265 *knew = alc880_control_templates[type];
3266 knew->name = kstrdup(name, GFP_KERNEL);
3269 knew->private_value = val;
3270 spec->num_kctl_used++;
3274 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3275 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3276 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3277 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3278 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3279 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3280 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3281 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3282 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3283 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3284 #define ALC880_PIN_CD_NID 0x1c
3286 /* fill in the dac_nids table from the parsed pin configuration */
3287 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3288 const struct auto_pin_cfg *cfg)
3294 memset(assigned, 0, sizeof(assigned));
3295 spec->multiout.dac_nids = spec->private_dac_nids;
3297 /* check the pins hardwired to audio widget */
3298 for (i = 0; i < cfg->line_outs; i++) {
3299 nid = cfg->line_out_pins[i];
3300 if (alc880_is_fixed_pin(nid)) {
3301 int idx = alc880_fixed_pin_idx(nid);
3302 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3306 /* left pins can be connect to any audio widget */
3307 for (i = 0; i < cfg->line_outs; i++) {
3308 nid = cfg->line_out_pins[i];
3309 if (alc880_is_fixed_pin(nid))
3311 /* search for an empty channel */
3312 for (j = 0; j < cfg->line_outs; j++) {
3314 spec->multiout.dac_nids[i] =
3315 alc880_idx_to_dac(j);
3321 spec->multiout.num_dacs = cfg->line_outs;
3325 /* add playback controls from the parsed DAC table */
3326 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3327 const struct auto_pin_cfg *cfg)
3330 static const char *chname[4] = {
3331 "Front", "Surround", NULL /*CLFE*/, "Side"
3336 for (i = 0; i < cfg->line_outs; i++) {
3337 if (!spec->multiout.dac_nids[i])
3339 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3342 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3343 "Center Playback Volume",
3344 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3348 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3349 "LFE Playback Volume",
3350 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3354 err = add_control(spec, ALC_CTL_BIND_MUTE,
3355 "Center Playback Switch",
3356 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3360 err = add_control(spec, ALC_CTL_BIND_MUTE,
3361 "LFE Playback Switch",
3362 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3367 sprintf(name, "%s Playback Volume", chname[i]);
3368 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3369 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3373 sprintf(name, "%s Playback Switch", chname[i]);
3374 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3375 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3384 /* add playback controls for speaker and HP outputs */
3385 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3395 if (alc880_is_fixed_pin(pin)) {
3396 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3397 /* specify the DAC as the extra output */
3398 if (!spec->multiout.hp_nid)
3399 spec->multiout.hp_nid = nid;
3401 spec->multiout.extra_out_nid[0] = nid;
3402 /* control HP volume/switch on the output mixer amp */
3403 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3404 sprintf(name, "%s Playback Volume", pfx);
3405 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3406 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3409 sprintf(name, "%s Playback Switch", pfx);
3410 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3411 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3414 } else if (alc880_is_multi_pin(pin)) {
3415 /* set manual connection */
3416 /* we have only a switch on HP-out PIN */
3417 sprintf(name, "%s Playback Switch", pfx);
3418 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3419 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3426 /* create input playback/capture controls for the given pin */
3427 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3428 const char *ctlname,
3429 int idx, hda_nid_t mix_nid)
3434 sprintf(name, "%s Playback Volume", ctlname);
3435 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3436 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3439 sprintf(name, "%s Playback Switch", ctlname);
3440 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3441 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3447 /* create playback/capture controls for input pins */
3448 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3449 const struct auto_pin_cfg *cfg)
3451 struct hda_input_mux *imux = &spec->private_imux;
3454 for (i = 0; i < AUTO_PIN_LAST; i++) {
3455 if (alc880_is_input_pin(cfg->input_pins[i])) {
3456 idx = alc880_input_pin_idx(cfg->input_pins[i]);
3457 err = new_analog_input(spec, cfg->input_pins[i],
3458 auto_pin_cfg_labels[i],
3462 imux->items[imux->num_items].label =
3463 auto_pin_cfg_labels[i];
3464 imux->items[imux->num_items].index =
3465 alc880_input_pin_idx(cfg->input_pins[i]);
3472 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3473 hda_nid_t nid, int pin_type,
3477 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3479 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3481 /* need the manual connection? */
3482 if (alc880_is_multi_pin(nid)) {
3483 struct alc_spec *spec = codec->spec;
3484 int idx = alc880_multi_pin_idx(nid);
3485 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3486 AC_VERB_SET_CONNECT_SEL,
3487 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3491 static int get_pin_type(int line_out_type)
3493 if (line_out_type == AUTO_PIN_HP_OUT)
3499 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3501 struct alc_spec *spec = codec->spec;
3504 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3505 for (i = 0; i < spec->autocfg.line_outs; i++) {
3506 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3507 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3508 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3512 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3514 struct alc_spec *spec = codec->spec;
3517 pin = spec->autocfg.speaker_pins[0];
3518 if (pin) /* connect to front */
3519 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3520 pin = spec->autocfg.hp_pins[0];
3521 if (pin) /* connect to front */
3522 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3525 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3527 struct alc_spec *spec = codec->spec;
3530 for (i = 0; i < AUTO_PIN_LAST; i++) {
3531 hda_nid_t nid = spec->autocfg.input_pins[i];
3532 if (alc880_is_input_pin(nid)) {
3533 snd_hda_codec_write(codec, nid, 0,
3534 AC_VERB_SET_PIN_WIDGET_CONTROL,
3535 i <= AUTO_PIN_FRONT_MIC ?
3536 PIN_VREF80 : PIN_IN);
3537 if (nid != ALC880_PIN_CD_NID)
3538 snd_hda_codec_write(codec, nid, 0,
3539 AC_VERB_SET_AMP_GAIN_MUTE,
3545 /* parse the BIOS configuration and set up the alc_spec */
3546 /* return 1 if successful, 0 if the proper config is not found,
3547 * or a negative error code
3549 static int alc880_parse_auto_config(struct hda_codec *codec)
3551 struct alc_spec *spec = codec->spec;
3553 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3555 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3559 if (!spec->autocfg.line_outs)
3560 return 0; /* can't find valid BIOS pin config */
3562 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3565 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3568 err = alc880_auto_create_extra_out(spec,
3569 spec->autocfg.speaker_pins[0],
3573 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3577 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3581 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3583 if (spec->autocfg.dig_out_pin)
3584 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3585 if (spec->autocfg.dig_in_pin)
3586 spec->dig_in_nid = ALC880_DIGIN_NID;
3588 if (spec->kctl_alloc)
3589 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3591 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3593 spec->num_mux_defs = 1;
3594 spec->input_mux = &spec->private_imux;
3599 /* additional initialization for auto-configuration model */
3600 static void alc880_auto_init(struct hda_codec *codec)
3602 alc880_auto_init_multi_out(codec);
3603 alc880_auto_init_extra_out(codec);
3604 alc880_auto_init_analog_input(codec);
3608 * OK, here we have finally the patch for ALC880
3611 static int patch_alc880(struct hda_codec *codec)
3613 struct alc_spec *spec;
3617 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3623 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3626 if (board_config < 0) {
3627 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3628 "trying auto-probe from BIOS...\n");
3629 board_config = ALC880_AUTO;
3632 if (board_config == ALC880_AUTO) {
3633 /* automatic parse from the BIOS config */
3634 err = alc880_parse_auto_config(codec);
3640 "hda_codec: Cannot set up configuration "
3641 "from BIOS. Using 3-stack mode...\n");
3642 board_config = ALC880_3ST;
3646 if (board_config != ALC880_AUTO)
3647 setup_preset(spec, &alc880_presets[board_config]);
3649 spec->stream_name_analog = "ALC880 Analog";
3650 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3651 spec->stream_analog_capture = &alc880_pcm_analog_capture;
3652 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
3654 spec->stream_name_digital = "ALC880 Digital";
3655 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3656 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3658 if (!spec->adc_nids && spec->input_mux) {
3659 /* check whether NID 0x07 is valid */
3660 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3662 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3663 if (wcap != AC_WID_AUD_IN) {
3664 spec->adc_nids = alc880_adc_nids_alt;
3665 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3666 spec->mixers[spec->num_mixers] =
3667 alc880_capture_alt_mixer;
3670 spec->adc_nids = alc880_adc_nids;
3671 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3672 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3677 spec->vmaster_nid = 0x0c;
3679 codec->patch_ops = alc_patch_ops;
3680 if (board_config == ALC880_AUTO)
3681 spec->init_hook = alc880_auto_init;
3682 #ifdef CONFIG_SND_HDA_POWER_SAVE
3683 if (!spec->loopback.amplist)
3684 spec->loopback.amplist = alc880_loopbacks;
3695 static hda_nid_t alc260_dac_nids[1] = {
3700 static hda_nid_t alc260_adc_nids[1] = {
3705 static hda_nid_t alc260_adc_nids_alt[1] = {
3710 static hda_nid_t alc260_hp_adc_nids[2] = {
3715 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
3716 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3718 static hda_nid_t alc260_dual_adc_nids[2] = {
3723 #define ALC260_DIGOUT_NID 0x03
3724 #define ALC260_DIGIN_NID 0x06
3726 static struct hda_input_mux alc260_capture_source = {
3730 { "Front Mic", 0x1 },
3736 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3737 * headphone jack and the internal CD lines since these are the only pins at
3738 * which audio can appear. For flexibility, also allow the option of
3739 * recording the mixer output on the second ADC (ADC0 doesn't have a
3740 * connection to the mixer output).
3742 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3746 { "Mic/Line", 0x0 },
3748 { "Headphone", 0x2 },
3754 { "Mic/Line", 0x0 },
3756 { "Headphone", 0x2 },
3763 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3764 * the Fujitsu S702x, but jacks are marked differently.
3766 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3773 { "Headphone", 0x5 },
3782 { "Headphone", 0x6 },
3788 * This is just place-holder, so there's something for alc_build_pcms to look
3789 * at when it calculates the maximum number of channels. ALC260 has no mixer
3790 * element which allows changing the channel mode, so the verb list is
3793 static struct hda_channel_mode alc260_modes[1] = {
3798 /* Mixer combinations
3800 * basic: base_output + input + pc_beep + capture
3801 * HP: base_output + input + capture_alt
3802 * HP_3013: hp_3013 + input + capture
3803 * fujitsu: fujitsu + capture
3804 * acer: acer + capture
3807 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3808 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3809 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3810 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3811 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3812 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3813 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3817 static struct snd_kcontrol_new alc260_input_mixer[] = {
3818 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3819 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3820 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3821 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3822 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3823 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3824 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3825 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3829 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3830 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3831 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3835 /* update HP, line and mono out pins according to the master switch */
3836 static void alc260_hp_master_update(struct hda_codec *codec,
3837 hda_nid_t hp, hda_nid_t line,
3840 struct alc_spec *spec = codec->spec;
3841 unsigned int val = spec->master_sw ? PIN_HP : 0;
3842 /* change HP and line-out pins */
3843 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3845 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3847 /* mono (speaker) depending on the HP jack sense */
3848 val = (val && !spec->jack_present) ? PIN_OUT : 0;
3849 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3853 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
3854 struct snd_ctl_elem_value *ucontrol)
3856 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3857 struct alc_spec *spec = codec->spec;
3858 *ucontrol->value.integer.value = spec->master_sw;
3862 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
3863 struct snd_ctl_elem_value *ucontrol)
3865 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3866 struct alc_spec *spec = codec->spec;
3867 int val = !!*ucontrol->value.integer.value;
3868 hda_nid_t hp, line, mono;
3870 if (val == spec->master_sw)
3872 spec->master_sw = val;
3873 hp = (kcontrol->private_value >> 16) & 0xff;
3874 line = (kcontrol->private_value >> 8) & 0xff;
3875 mono = kcontrol->private_value & 0xff;
3876 alc260_hp_master_update(codec, hp, line, mono);
3880 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
3882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3883 .name = "Master Playback Switch",
3884 .info = snd_ctl_boolean_mono_info,
3885 .get = alc260_hp_master_sw_get,
3886 .put = alc260_hp_master_sw_put,
3887 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
3889 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3890 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3891 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3892 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3893 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
3895 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3899 static struct hda_verb alc260_hp_unsol_verbs[] = {
3900 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3904 static void alc260_hp_automute(struct hda_codec *codec)
3906 struct alc_spec *spec = codec->spec;
3907 unsigned int present;
3909 present = snd_hda_codec_read(codec, 0x10, 0,
3910 AC_VERB_GET_PIN_SENSE, 0);
3911 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
3912 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
3915 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
3917 if ((res >> 26) == ALC880_HP_EVENT)
3918 alc260_hp_automute(codec);
3921 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3923 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3924 .name = "Master Playback Switch",
3925 .info = snd_ctl_boolean_mono_info,
3926 .get = alc260_hp_master_sw_get,
3927 .put = alc260_hp_master_sw_put,
3928 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
3930 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3931 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3932 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3933 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3934 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3935 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3936 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3937 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3941 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
3942 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3946 static void alc260_hp_3013_automute(struct hda_codec *codec)
3948 struct alc_spec *spec = codec->spec;
3949 unsigned int present;
3951 present = snd_hda_codec_read(codec, 0x15, 0,
3952 AC_VERB_GET_PIN_SENSE, 0);
3953 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
3954 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
3957 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
3960 if ((res >> 26) == ALC880_HP_EVENT)
3961 alc260_hp_3013_automute(codec);
3964 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
3965 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
3967 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3968 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3969 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3970 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3971 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3972 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3973 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3974 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3975 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3976 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3977 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3978 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3979 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3983 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
3984 * versions of the ALC260 don't act on requests to enable mic bias from NID
3985 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
3986 * datasheet doesn't mention this restriction. At this stage it's not clear
3987 * whether this behaviour is intentional or is a hardware bug in chip
3988 * revisions available in early 2006. Therefore for now allow the
3989 * "Headphone Jack Mode" control to span all choices, but if it turns out
3990 * that the lack of mic bias for this NID is intentional we could change the
3991 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3993 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3994 * don't appear to make the mic bias available from the "line" jack, even
3995 * though the NID used for this jack (0x14) can supply it. The theory is
3996 * that perhaps Acer have included blocking capacitors between the ALC260
3997 * and the output jack. If this turns out to be the case for all such
3998 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3999 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4001 * The C20x Tablet series have a mono internal speaker which is controlled
4002 * via the chip's Mono sum widget and pin complex, so include the necessary
4003 * controls for such models. On models without a "mono speaker" the control
4004 * won't do anything.
4006 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4007 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4008 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4009 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4010 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4012 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4014 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4015 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4016 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4017 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4018 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4019 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4020 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4021 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4022 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4023 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4027 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4028 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4030 static struct snd_kcontrol_new alc260_will_mixer[] = {
4031 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4032 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4033 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4034 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4035 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4036 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4037 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4038 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4039 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4040 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4041 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4042 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4046 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4047 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4049 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4050 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4051 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4052 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4053 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4054 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4055 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4056 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4057 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4058 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4059 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4063 /* capture mixer elements */
4064 static struct snd_kcontrol_new alc260_capture_mixer[] = {
4065 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4066 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4067 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4068 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4070 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4071 /* The multiple "Capture Source" controls confuse alsamixer
4072 * So call somewhat different..
4074 /* .name = "Capture Source", */
4075 .name = "Input Source",
4077 .info = alc_mux_enum_info,
4078 .get = alc_mux_enum_get,
4079 .put = alc_mux_enum_put,
4084 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4085 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4086 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4088 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4089 /* The multiple "Capture Source" controls confuse alsamixer
4090 * So call somewhat different..
4092 /* .name = "Capture Source", */
4093 .name = "Input Source",
4095 .info = alc_mux_enum_info,
4096 .get = alc_mux_enum_get,
4097 .put = alc_mux_enum_put,
4103 * initialization verbs
4105 static struct hda_verb alc260_init_verbs[] = {
4106 /* Line In pin widget for input */
4107 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4108 /* CD pin widget for input */
4109 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4110 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4111 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4112 /* Mic2 (front panel) pin widget for input and vref at 80% */
4113 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4114 /* LINE-2 is used for line-out in rear */
4115 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4116 /* select line-out */
4117 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4119 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4121 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4123 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4124 /* mute capture amp left and right */
4125 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4126 /* set connection select to line in (default select for this ADC) */
4127 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4128 /* mute capture amp left and right */
4129 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4130 /* set connection select to line in (default select for this ADC) */
4131 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4132 /* set vol=0 Line-Out mixer amp left and right */
4133 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4134 /* unmute pin widget amp left and right (no gain on this amp) */
4135 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4136 /* set vol=0 HP mixer amp left and right */
4137 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4138 /* unmute pin widget amp left and right (no gain on this amp) */
4139 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4140 /* set vol=0 Mono mixer amp left and right */
4141 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4142 /* unmute pin widget amp left and right (no gain on this amp) */
4143 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4144 /* unmute LINE-2 out pin */
4145 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4146 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4149 /* mute analog inputs */
4150 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4151 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4152 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4153 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4154 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4155 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4156 /* mute Front out path */
4157 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4158 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4159 /* mute Headphone out path */
4160 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4161 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4162 /* mute Mono out path */
4163 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4164 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4168 #if 0 /* should be identical with alc260_init_verbs? */
4169 static struct hda_verb alc260_hp_init_verbs[] = {
4170 /* Headphone and output */
4171 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4173 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4174 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4175 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4176 /* Mic2 (front panel) pin widget for input and vref at 80% */
4177 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4178 /* Line In pin widget for input */
4179 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4180 /* Line-2 pin widget for output */
4181 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4182 /* CD pin widget for input */
4183 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4184 /* unmute amp left and right */
4185 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4186 /* set connection select to line in (default select for this ADC) */
4187 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4188 /* unmute Line-Out mixer amp left and right (volume = 0) */
4189 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4190 /* mute pin widget amp left and right (no gain on this amp) */
4191 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4192 /* unmute HP mixer amp left and right (volume = 0) */
4193 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4194 /* mute pin widget amp left and right (no gain on this amp) */
4195 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4196 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4199 /* mute analog inputs */
4200 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4201 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4202 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4203 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4204 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4205 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4206 /* Unmute Front out path */
4207 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4208 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4209 /* Unmute Headphone out path */
4210 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4211 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4212 /* Unmute Mono out path */
4213 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4214 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4219 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4220 /* Line out and output */
4221 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4223 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4224 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4225 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4226 /* Mic2 (front panel) pin widget for input and vref at 80% */
4227 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4228 /* Line In pin widget for input */
4229 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4230 /* Headphone pin widget for output */
4231 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4232 /* CD pin widget for input */
4233 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4234 /* unmute amp left and right */
4235 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4236 /* set connection select to line in (default select for this ADC) */
4237 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4238 /* unmute Line-Out mixer amp left and right (volume = 0) */
4239 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4240 /* mute pin widget amp left and right (no gain on this amp) */
4241 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4242 /* unmute HP mixer amp left and right (volume = 0) */
4243 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4244 /* mute pin widget amp left and right (no gain on this amp) */
4245 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4246 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4249 /* mute analog inputs */
4250 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4251 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4252 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4253 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4254 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4255 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4256 /* Unmute Front out path */
4257 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4258 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4259 /* Unmute Headphone out path */
4260 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4261 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4262 /* Unmute Mono out path */
4263 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4264 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4268 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4269 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4270 * audio = 0x16, internal speaker = 0x10.
4272 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4273 /* Disable all GPIOs */
4274 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4275 /* Internal speaker is connected to headphone pin */
4276 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4277 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4278 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4279 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4280 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4281 /* Ensure all other unused pins are disabled and muted. */
4282 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4283 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4284 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4285 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4286 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4287 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4288 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4289 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4291 /* Disable digital (SPDIF) pins */
4292 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4293 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4295 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4296 * when acting as an output.
4298 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4300 /* Start with output sum widgets muted and their output gains at min */
4301 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4302 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4303 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4304 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4305 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4306 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4307 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4308 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4309 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4311 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4312 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4313 /* Unmute Line1 pin widget output buffer since it starts as an output.
4314 * If the pin mode is changed by the user the pin mode control will
4315 * take care of enabling the pin's input/output buffers as needed.
4316 * Therefore there's no need to enable the input buffer at this
4319 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4320 /* Unmute input buffer of pin widget used for Line-in (no equiv
4323 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4325 /* Mute capture amp left and right */
4326 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4327 /* Set ADC connection select to match default mixer setting - line
4330 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4332 /* Do the same for the second ADC: mute capture input amp and
4333 * set ADC connection to line in (on mic1 pin)
4335 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4336 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4338 /* Mute all inputs to mixer widget (even unconnected ones) */
4339 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4340 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4341 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4342 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4343 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4344 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4345 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4346 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4351 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4352 * similar laptops (adapted from Fujitsu init verbs).
4354 static struct hda_verb alc260_acer_init_verbs[] = {
4355 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4356 * the headphone jack. Turn this on and rely on the standard mute
4357 * methods whenever the user wants to turn these outputs off.
4359 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4360 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4361 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4362 /* Internal speaker/Headphone jack is connected to Line-out pin */
4363 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4364 /* Internal microphone/Mic jack is connected to Mic1 pin */
4365 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4366 /* Line In jack is connected to Line1 pin */
4367 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4368 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4369 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4370 /* Ensure all other unused pins are disabled and muted. */
4371 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4372 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4373 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4374 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4375 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4376 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4377 /* Disable digital (SPDIF) pins */
4378 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4379 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4381 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4382 * bus when acting as outputs.
4384 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4385 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4387 /* Start with output sum widgets muted and their output gains at min */
4388 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4389 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4390 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4391 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4392 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4394 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4395 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4396 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4398 /* Unmute Line-out pin widget amp left and right
4399 * (no equiv mixer ctrl)
4401 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4402 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4403 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4404 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4405 * inputs. If the pin mode is changed by the user the pin mode control
4406 * will take care of enabling the pin's input/output buffers as needed.
4407 * Therefore there's no need to enable the input buffer at this
4410 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4411 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4413 /* Mute capture amp left and right */
4414 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4415 /* Set ADC connection select to match default mixer setting - mic
4418 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4420 /* Do similar with the second ADC: mute capture input amp and
4421 * set ADC connection to mic to match ALSA's default state.
4423 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4424 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4426 /* Mute all inputs to mixer widget (even unconnected ones) */
4427 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4428 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4429 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4430 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4431 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4432 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4433 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4434 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4439 static struct hda_verb alc260_will_verbs[] = {
4440 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4441 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4442 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4443 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4444 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4445 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4449 static struct hda_verb alc260_replacer_672v_verbs[] = {
4450 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4451 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4452 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4454 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4455 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4456 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4458 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4462 /* toggle speaker-output according to the hp-jack state */
4463 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4465 unsigned int present;
4467 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4468 present = snd_hda_codec_read(codec, 0x0f, 0,
4469 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4471 snd_hda_codec_write_cache(codec, 0x01, 0,
4472 AC_VERB_SET_GPIO_DATA, 1);
4473 snd_hda_codec_write_cache(codec, 0x0f, 0,
4474 AC_VERB_SET_PIN_WIDGET_CONTROL,
4477 snd_hda_codec_write_cache(codec, 0x01, 0,
4478 AC_VERB_SET_GPIO_DATA, 0);
4479 snd_hda_codec_write_cache(codec, 0x0f, 0,
4480 AC_VERB_SET_PIN_WIDGET_CONTROL,
4485 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4488 if ((res >> 26) == ALC880_HP_EVENT)
4489 alc260_replacer_672v_automute(codec);
4492 /* Test configuration for debugging, modelled after the ALC880 test
4495 #ifdef CONFIG_SND_DEBUG
4496 static hda_nid_t alc260_test_dac_nids[1] = {
4499 static hda_nid_t alc260_test_adc_nids[2] = {
4502 /* For testing the ALC260, each input MUX needs its own definition since
4503 * the signal assignments are different. This assumes that the first ADC
4506 static struct hda_input_mux alc260_test_capture_sources[2] = {
4510 { "MIC1 pin", 0x0 },
4511 { "MIC2 pin", 0x1 },
4512 { "LINE1 pin", 0x2 },
4513 { "LINE2 pin", 0x3 },
4515 { "LINE-OUT pin", 0x5 },
4516 { "HP-OUT pin", 0x6 },
4522 { "MIC1 pin", 0x0 },
4523 { "MIC2 pin", 0x1 },
4524 { "LINE1 pin", 0x2 },
4525 { "LINE2 pin", 0x3 },
4528 { "LINE-OUT pin", 0x6 },
4529 { "HP-OUT pin", 0x7 },
4533 static struct snd_kcontrol_new alc260_test_mixer[] = {
4534 /* Output driver widgets */
4535 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4536 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4537 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4538 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4539 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4540 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4542 /* Modes for retasking pin widgets
4543 * Note: the ALC260 doesn't seem to act on requests to enable mic
4544 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4545 * mention this restriction. At this stage it's not clear whether
4546 * this behaviour is intentional or is a hardware bug in chip
4547 * revisions available at least up until early 2006. Therefore for
4548 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4549 * choices, but if it turns out that the lack of mic bias for these
4550 * NIDs is intentional we could change their modes from
4551 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4553 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4554 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4555 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4556 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4557 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4558 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4560 /* Loopback mixer controls */
4561 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4562 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4563 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4564 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4565 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4566 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4567 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4568 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4569 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4570 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4571 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4572 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4573 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4574 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4575 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4576 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4578 /* Controls for GPIO pins, assuming they are configured as outputs */
4579 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4580 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4581 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4582 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4584 /* Switches to allow the digital IO pins to be enabled. The datasheet
4585 * is ambigious as to which NID is which; testing on laptops which
4586 * make this output available should provide clarification.
4588 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4589 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4591 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4592 * this output to turn on an external amplifier.
4594 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4595 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4599 static struct hda_verb alc260_test_init_verbs[] = {
4600 /* Enable all GPIOs as outputs with an initial value of 0 */
4601 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4602 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4603 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4605 /* Enable retasking pins as output, initially without power amp */
4606 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4607 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4608 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4609 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4610 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4611 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4613 /* Disable digital (SPDIF) pins initially, but users can enable
4614 * them via a mixer switch. In the case of SPDIF-out, this initverb
4615 * payload also sets the generation to 0, output to be in "consumer"
4616 * PCM format, copyright asserted, no pre-emphasis and no validity
4619 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4620 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4622 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4623 * OUT1 sum bus when acting as an output.
4625 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4626 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4627 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4628 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4630 /* Start with output sum widgets muted and their output gains at min */
4631 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4632 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4633 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4634 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4635 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4636 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4637 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4638 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4639 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4641 /* Unmute retasking pin widget output buffers since the default
4642 * state appears to be output. As the pin mode is changed by the
4643 * user the pin mode control will take care of enabling the pin's
4644 * input/output buffers as needed.
4646 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4647 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4648 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4649 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4650 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4651 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4652 /* Also unmute the mono-out pin widget */
4653 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4655 /* Mute capture amp left and right */
4656 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4657 /* Set ADC connection select to match default mixer setting (mic1
4660 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4662 /* Do the same for the second ADC: mute capture input amp and
4663 * set ADC connection to mic1 pin
4665 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4666 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4668 /* Mute all inputs to mixer widget (even unconnected ones) */
4669 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4670 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4671 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4672 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4673 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4674 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4675 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4676 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4682 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
4683 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
4685 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
4686 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
4689 * for BIOS auto-configuration
4692 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4696 unsigned long vol_val, sw_val;
4700 if (nid >= 0x0f && nid < 0x11) {
4701 nid_vol = nid - 0x7;
4702 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4703 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4704 } else if (nid == 0x11) {
4705 nid_vol = nid - 0x7;
4706 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4707 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4708 } else if (nid >= 0x12 && nid <= 0x15) {
4710 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4711 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4715 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4716 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4719 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4720 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4726 /* add playback controls from the parsed DAC table */
4727 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4728 const struct auto_pin_cfg *cfg)
4733 spec->multiout.num_dacs = 1;
4734 spec->multiout.dac_nids = spec->private_dac_nids;
4735 spec->multiout.dac_nids[0] = 0x02;
4737 nid = cfg->line_out_pins[0];
4739 err = alc260_add_playback_controls(spec, nid, "Front");
4744 nid = cfg->speaker_pins[0];
4746 err = alc260_add_playback_controls(spec, nid, "Speaker");
4751 nid = cfg->hp_pins[0];
4753 err = alc260_add_playback_controls(spec, nid, "Headphone");
4760 /* create playback/capture controls for input pins */
4761 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4762 const struct auto_pin_cfg *cfg)
4764 struct hda_input_mux *imux = &spec->private_imux;
4767 for (i = 0; i < AUTO_PIN_LAST; i++) {
4768 if (cfg->input_pins[i] >= 0x12) {
4769 idx = cfg->input_pins[i] - 0x12;
4770 err = new_analog_input(spec, cfg->input_pins[i],
4771 auto_pin_cfg_labels[i], idx,
4775 imux->items[imux->num_items].label =
4776 auto_pin_cfg_labels[i];
4777 imux->items[imux->num_items].index = idx;
4780 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4781 idx = cfg->input_pins[i] - 0x09;
4782 err = new_analog_input(spec, cfg->input_pins[i],
4783 auto_pin_cfg_labels[i], idx,
4787 imux->items[imux->num_items].label =
4788 auto_pin_cfg_labels[i];
4789 imux->items[imux->num_items].index = idx;
4796 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4797 hda_nid_t nid, int pin_type,
4801 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4803 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4805 /* need the manual connection? */
4807 int idx = nid - 0x12;
4808 snd_hda_codec_write(codec, idx + 0x0b, 0,
4809 AC_VERB_SET_CONNECT_SEL, sel_idx);
4813 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4815 struct alc_spec *spec = codec->spec;
4818 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4819 nid = spec->autocfg.line_out_pins[0];
4821 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4822 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4825 nid = spec->autocfg.speaker_pins[0];
4827 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4829 nid = spec->autocfg.hp_pins[0];
4831 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4834 #define ALC260_PIN_CD_NID 0x16
4835 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4837 struct alc_spec *spec = codec->spec;
4840 for (i = 0; i < AUTO_PIN_LAST; i++) {
4841 hda_nid_t nid = spec->autocfg.input_pins[i];
4843 snd_hda_codec_write(codec, nid, 0,
4844 AC_VERB_SET_PIN_WIDGET_CONTROL,
4845 i <= AUTO_PIN_FRONT_MIC ?
4846 PIN_VREF80 : PIN_IN);
4847 if (nid != ALC260_PIN_CD_NID)
4848 snd_hda_codec_write(codec, nid, 0,
4849 AC_VERB_SET_AMP_GAIN_MUTE,
4856 * generic initialization of ADC, input mixers and output mixers
4858 static struct hda_verb alc260_volume_init_verbs[] = {
4860 * Unmute ADC0-1 and set the default input to mic-in
4862 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4863 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4864 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4865 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4867 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4869 * Note: PASD motherboards uses the Line In 2 as the input for
4870 * front panel mic (mic 2)
4872 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4873 /* mute analog inputs */
4874 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4875 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4876 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4877 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4878 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4881 * Set up output mixers (0x08 - 0x0a)
4883 /* set vol=0 to output mixers */
4884 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4885 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4886 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4887 /* set up input amps for analog loopback */
4888 /* Amp Indices: DAC = 0, mixer = 1 */
4889 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4890 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4891 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4892 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4893 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4894 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4899 static int alc260_parse_auto_config(struct hda_codec *codec)
4901 struct alc_spec *spec = codec->spec;
4904 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4906 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4910 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4913 if (!spec->kctl_alloc)
4914 return 0; /* can't find valid BIOS pin config */
4915 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4919 spec->multiout.max_channels = 2;
4921 if (spec->autocfg.dig_out_pin)
4922 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4923 if (spec->kctl_alloc)
4924 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4926 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4928 spec->num_mux_defs = 1;
4929 spec->input_mux = &spec->private_imux;
4931 /* check whether NID 0x04 is valid */
4932 wcap = get_wcaps(codec, 0x04);
4933 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4934 if (wcap != AC_WID_AUD_IN) {
4935 spec->adc_nids = alc260_adc_nids_alt;
4936 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4937 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4939 spec->adc_nids = alc260_adc_nids;
4940 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4941 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4948 /* additional initialization for auto-configuration model */
4949 static void alc260_auto_init(struct hda_codec *codec)
4951 alc260_auto_init_multi_out(codec);
4952 alc260_auto_init_analog_input(codec);
4955 #ifdef CONFIG_SND_HDA_POWER_SAVE
4956 static struct hda_amp_list alc260_loopbacks[] = {
4957 { 0x07, HDA_INPUT, 0 },
4958 { 0x07, HDA_INPUT, 1 },
4959 { 0x07, HDA_INPUT, 2 },
4960 { 0x07, HDA_INPUT, 3 },
4961 { 0x07, HDA_INPUT, 4 },
4967 * ALC260 configurations
4969 static const char *alc260_models[ALC260_MODEL_LAST] = {
4970 [ALC260_BASIC] = "basic",
4972 [ALC260_HP_3013] = "hp-3013",
4973 [ALC260_FUJITSU_S702X] = "fujitsu",
4974 [ALC260_ACER] = "acer",
4975 [ALC260_WILL] = "will",
4976 [ALC260_REPLACER_672V] = "replacer",
4977 #ifdef CONFIG_SND_DEBUG
4978 [ALC260_TEST] = "test",
4980 [ALC260_AUTO] = "auto",
4983 static struct snd_pci_quirk alc260_cfg_tbl[] = {
4984 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4985 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4986 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4987 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4988 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4989 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4990 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4991 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4992 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4993 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4994 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4995 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4996 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4997 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4998 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4999 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5000 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5001 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5005 static struct alc_config_preset alc260_presets[] = {
5007 .mixers = { alc260_base_output_mixer,
5009 alc260_pc_beep_mixer,
5010 alc260_capture_mixer },
5011 .init_verbs = { alc260_init_verbs },
5012 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5013 .dac_nids = alc260_dac_nids,
5014 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5015 .adc_nids = alc260_adc_nids,
5016 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5017 .channel_mode = alc260_modes,
5018 .input_mux = &alc260_capture_source,
5021 .mixers = { alc260_hp_output_mixer,
5023 alc260_capture_alt_mixer },
5024 .init_verbs = { alc260_init_verbs,
5025 alc260_hp_unsol_verbs },
5026 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5027 .dac_nids = alc260_dac_nids,
5028 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5029 .adc_nids = alc260_hp_adc_nids,
5030 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5031 .channel_mode = alc260_modes,
5032 .input_mux = &alc260_capture_source,
5033 .unsol_event = alc260_hp_unsol_event,
5034 .init_hook = alc260_hp_automute,
5036 [ALC260_HP_3013] = {
5037 .mixers = { alc260_hp_3013_mixer,
5039 alc260_capture_alt_mixer },
5040 .init_verbs = { alc260_hp_3013_init_verbs,
5041 alc260_hp_3013_unsol_verbs },
5042 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5043 .dac_nids = alc260_dac_nids,
5044 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5045 .adc_nids = alc260_hp_adc_nids,
5046 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5047 .channel_mode = alc260_modes,
5048 .input_mux = &alc260_capture_source,
5049 .unsol_event = alc260_hp_3013_unsol_event,
5050 .init_hook = alc260_hp_3013_automute,
5052 [ALC260_FUJITSU_S702X] = {
5053 .mixers = { alc260_fujitsu_mixer,
5054 alc260_capture_mixer },
5055 .init_verbs = { alc260_fujitsu_init_verbs },
5056 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5057 .dac_nids = alc260_dac_nids,
5058 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5059 .adc_nids = alc260_dual_adc_nids,
5060 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5061 .channel_mode = alc260_modes,
5062 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5063 .input_mux = alc260_fujitsu_capture_sources,
5066 .mixers = { alc260_acer_mixer,
5067 alc260_capture_mixer },
5068 .init_verbs = { alc260_acer_init_verbs },
5069 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5070 .dac_nids = alc260_dac_nids,
5071 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5072 .adc_nids = alc260_dual_adc_nids,
5073 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5074 .channel_mode = alc260_modes,
5075 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5076 .input_mux = alc260_acer_capture_sources,
5079 .mixers = { alc260_will_mixer,
5080 alc260_capture_mixer },
5081 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5082 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5083 .dac_nids = alc260_dac_nids,
5084 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5085 .adc_nids = alc260_adc_nids,
5086 .dig_out_nid = ALC260_DIGOUT_NID,
5087 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5088 .channel_mode = alc260_modes,
5089 .input_mux = &alc260_capture_source,
5091 [ALC260_REPLACER_672V] = {
5092 .mixers = { alc260_replacer_672v_mixer,
5093 alc260_capture_mixer },
5094 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5095 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5096 .dac_nids = alc260_dac_nids,
5097 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5098 .adc_nids = alc260_adc_nids,
5099 .dig_out_nid = ALC260_DIGOUT_NID,
5100 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5101 .channel_mode = alc260_modes,
5102 .input_mux = &alc260_capture_source,
5103 .unsol_event = alc260_replacer_672v_unsol_event,
5104 .init_hook = alc260_replacer_672v_automute,
5106 #ifdef CONFIG_SND_DEBUG
5108 .mixers = { alc260_test_mixer,
5109 alc260_capture_mixer },
5110 .init_verbs = { alc260_test_init_verbs },
5111 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5112 .dac_nids = alc260_test_dac_nids,
5113 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5114 .adc_nids = alc260_test_adc_nids,
5115 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5116 .channel_mode = alc260_modes,
5117 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5118 .input_mux = alc260_test_capture_sources,
5123 static int patch_alc260(struct hda_codec *codec)
5125 struct alc_spec *spec;
5126 int err, board_config;
5128 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5134 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5137 if (board_config < 0) {
5138 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5139 "trying auto-probe from BIOS...\n");
5140 board_config = ALC260_AUTO;
5143 if (board_config == ALC260_AUTO) {
5144 /* automatic parse from the BIOS config */
5145 err = alc260_parse_auto_config(codec);
5151 "hda_codec: Cannot set up configuration "
5152 "from BIOS. Using base mode...\n");
5153 board_config = ALC260_BASIC;
5157 if (board_config != ALC260_AUTO)
5158 setup_preset(spec, &alc260_presets[board_config]);
5160 spec->stream_name_analog = "ALC260 Analog";
5161 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5162 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5164 spec->stream_name_digital = "ALC260 Digital";
5165 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5166 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5168 spec->vmaster_nid = 0x08;
5170 codec->patch_ops = alc_patch_ops;
5171 if (board_config == ALC260_AUTO)
5172 spec->init_hook = alc260_auto_init;
5173 #ifdef CONFIG_SND_HDA_POWER_SAVE
5174 if (!spec->loopback.amplist)
5175 spec->loopback.amplist = alc260_loopbacks;
5185 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5186 * configuration. Each pin widget can choose any input DACs and a mixer.
5187 * Each ADC is connected from a mixer of all inputs. This makes possible
5188 * 6-channel independent captures.
5190 * In addition, an independent DAC for the multi-playback (not used in this
5193 #define ALC882_DIGOUT_NID 0x06
5194 #define ALC882_DIGIN_NID 0x0a
5196 static struct hda_channel_mode alc882_ch_modes[1] = {
5200 static hda_nid_t alc882_dac_nids[4] = {
5201 /* front, rear, clfe, rear_surr */
5202 0x02, 0x03, 0x04, 0x05
5205 /* identical with ALC880 */
5206 #define alc882_adc_nids alc880_adc_nids
5207 #define alc882_adc_nids_alt alc880_adc_nids_alt
5210 /* FIXME: should be a matrix-type input source selection */
5212 static struct hda_input_mux alc882_capture_source = {
5216 { "Front Mic", 0x1 },
5221 #define alc882_mux_enum_info alc_mux_enum_info
5222 #define alc882_mux_enum_get alc_mux_enum_get
5224 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5225 struct snd_ctl_elem_value *ucontrol)
5227 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5228 struct alc_spec *spec = codec->spec;
5229 const struct hda_input_mux *imux = spec->input_mux;
5230 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5231 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5233 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5234 unsigned int i, idx;
5236 if (spec->num_adc_nids < 3)
5237 nid = capture_mixers[adc_idx + 1];
5239 nid = capture_mixers[adc_idx];
5240 idx = ucontrol->value.enumerated.item[0];
5241 if (idx >= imux->num_items)
5242 idx = imux->num_items - 1;
5243 if (*cur_val == idx)
5245 for (i = 0; i < imux->num_items; i++) {
5246 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5247 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5248 imux->items[i].index,
5258 static struct hda_verb alc882_3ST_ch2_init[] = {
5259 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5260 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5261 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5262 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5269 static struct hda_verb alc882_3ST_ch6_init[] = {
5270 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5271 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5272 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5273 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5274 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5275 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5279 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5280 { 2, alc882_3ST_ch2_init },
5281 { 6, alc882_3ST_ch6_init },
5287 static struct hda_verb alc882_sixstack_ch6_init[] = {
5288 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5289 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5290 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5291 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5298 static struct hda_verb alc882_sixstack_ch8_init[] = {
5299 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5300 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5301 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5302 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5306 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5307 { 6, alc882_sixstack_ch6_init },
5308 { 8, alc882_sixstack_ch8_init },
5312 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5318 static struct hda_verb alc885_mbp_ch2_init[] = {
5319 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5320 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5321 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5328 static struct hda_verb alc885_mbp_ch6_init[] = {
5329 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5330 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5331 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5332 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5333 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5337 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5338 { 2, alc885_mbp_ch2_init },
5339 { 6, alc885_mbp_ch6_init },
5343 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5344 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5346 static struct snd_kcontrol_new alc882_base_mixer[] = {
5347 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5348 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5349 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5350 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5351 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5352 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5353 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5354 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5355 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5356 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5357 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5358 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5359 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5360 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5361 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5362 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5363 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5364 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5365 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5366 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5367 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5368 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5369 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5373 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5374 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5375 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5376 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5377 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5378 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5379 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5380 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5381 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5382 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5383 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5386 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5387 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5388 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5389 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5390 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5391 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5392 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5393 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5394 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5395 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5396 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5397 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5401 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5402 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5403 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5404 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5405 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5406 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5407 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5408 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5409 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5410 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5411 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5412 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5413 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5414 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5418 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5419 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5421 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5422 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5423 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5424 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5425 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5426 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5427 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5428 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5429 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5430 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5431 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5432 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5433 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5434 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5438 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5439 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5440 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5441 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5442 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5443 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5444 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5445 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5446 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5447 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5448 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5449 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5450 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5454 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5456 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5457 .name = "Channel Mode",
5458 .info = alc_ch_mode_info,
5459 .get = alc_ch_mode_get,
5460 .put = alc_ch_mode_put,
5465 static struct hda_verb alc882_init_verbs[] = {
5466 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5467 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5468 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5469 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5471 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5472 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5473 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5475 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5476 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5477 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5479 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5480 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5481 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5483 /* Front Pin: output 0 (0x0c) */
5484 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5485 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5486 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5487 /* Rear Pin: output 1 (0x0d) */
5488 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5489 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5490 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5491 /* CLFE Pin: output 2 (0x0e) */
5492 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5493 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5494 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5495 /* Side Pin: output 3 (0x0f) */
5496 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5497 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5498 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5499 /* Mic (rear) pin: input vref at 80% */
5500 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5501 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5502 /* Front Mic pin: input vref at 80% */
5503 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5504 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5505 /* Line In pin: input */
5506 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5507 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5508 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5509 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5510 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5511 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5512 /* CD pin widget for input */
5513 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5515 /* FIXME: use matrix-type input source selection */
5516 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5517 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5518 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5519 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5520 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5523 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5524 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5525 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5528 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5529 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5530 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5532 /* ADC1: mute amp left and right */
5533 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5534 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5535 /* ADC2: mute amp left and right */
5536 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5537 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5538 /* ADC3: mute amp left and right */
5539 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5540 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5545 static struct hda_verb alc882_eapd_verbs[] = {
5546 /* change to EAPD mode */
5547 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5548 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5553 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5554 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5555 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5556 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5557 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5558 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5559 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5560 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5564 static struct hda_verb alc882_macpro_init_verbs[] = {
5565 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5566 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5567 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5568 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5569 /* Front Pin: output 0 (0x0c) */
5570 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5571 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5572 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5573 /* Front Mic pin: input vref at 80% */
5574 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5575 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5576 /* Speaker: output */
5577 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5578 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5579 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5580 /* Headphone output (output 0 - 0x0c) */
5581 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5582 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5583 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5585 /* FIXME: use matrix-type input source selection */
5586 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5587 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5588 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5589 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5590 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5591 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5593 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5594 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5595 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5596 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5598 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5599 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5600 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5601 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5602 /* ADC1: mute amp left and right */
5603 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5604 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5605 /* ADC2: mute amp left and right */
5606 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5607 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5608 /* ADC3: mute amp left and right */
5609 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5610 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5615 /* Macbook Pro rev3 */
5616 static struct hda_verb alc885_mbp3_init_verbs[] = {
5617 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5618 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5619 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5620 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5622 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5623 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5624 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5625 /* Front Pin: output 0 (0x0c) */
5626 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5627 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5628 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5629 /* HP Pin: output 0 (0x0d) */
5630 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5631 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5632 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5633 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5634 /* Mic (rear) pin: input vref at 80% */
5635 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5636 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5637 /* Front Mic pin: input vref at 80% */
5638 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5639 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5640 /* Line In pin: use output 1 when in LineOut mode */
5641 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5642 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5643 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5645 /* FIXME: use matrix-type input source selection */
5646 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5647 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5648 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5649 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5650 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5651 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5653 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5654 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5655 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5656 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5658 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5659 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5660 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5661 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5662 /* ADC1: mute amp left and right */
5663 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5664 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5665 /* ADC2: mute amp left and right */
5666 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5667 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5668 /* ADC3: mute amp left and right */
5669 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5670 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5675 /* iMac 24 mixer. */
5676 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5677 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5678 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5682 /* iMac 24 init verbs. */
5683 static struct hda_verb alc885_imac24_init_verbs[] = {
5684 /* Internal speakers: output 0 (0x0c) */
5685 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5686 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5687 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5688 /* Internal speakers: output 0 (0x0c) */
5689 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5690 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5691 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5692 /* Headphone: output 0 (0x0c) */
5693 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5694 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5695 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5696 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5697 /* Front Mic: input vref at 80% */
5698 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5699 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5703 /* Toggle speaker-output according to the hp-jack state */
5704 static void alc885_imac24_automute(struct hda_codec *codec)
5706 unsigned int present;
5708 present = snd_hda_codec_read(codec, 0x14, 0,
5709 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5710 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5711 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5712 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5713 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5716 /* Processes unsolicited events. */
5717 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5720 /* Headphone insertion or removal. */
5721 if ((res >> 26) == ALC880_HP_EVENT)
5722 alc885_imac24_automute(codec);
5725 static void alc885_mbp3_automute(struct hda_codec *codec)
5727 unsigned int present;
5729 present = snd_hda_codec_read(codec, 0x15, 0,
5730 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5731 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
5732 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5733 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5734 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5737 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5740 /* Headphone insertion or removal. */
5741 if ((res >> 26) == ALC880_HP_EVENT)
5742 alc885_mbp3_automute(codec);
5746 static struct hda_verb alc882_targa_verbs[] = {
5747 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5748 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5750 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5751 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5753 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5754 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5755 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5757 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5758 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5759 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5760 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5764 /* toggle speaker-output according to the hp-jack state */
5765 static void alc882_targa_automute(struct hda_codec *codec)
5767 unsigned int present;
5769 present = snd_hda_codec_read(codec, 0x14, 0,
5770 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5771 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5772 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5773 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5777 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5779 /* Looks like the unsol event is incompatible with the standard
5780 * definition. 4bit tag is placed at 26 bit!
5782 if (((res >> 26) == ALC880_HP_EVENT)) {
5783 alc882_targa_automute(codec);
5787 static struct hda_verb alc882_asus_a7j_verbs[] = {
5788 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5789 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5791 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5792 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5793 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5795 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5796 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5797 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5799 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5800 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5801 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5805 static struct hda_verb alc882_asus_a7m_verbs[] = {
5806 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5807 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5809 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5810 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5811 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5813 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5814 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5815 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5817 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5818 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5819 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5823 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5825 unsigned int gpiostate, gpiomask, gpiodir;
5827 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5828 AC_VERB_GET_GPIO_DATA, 0);
5831 gpiostate |= (1 << pin);
5833 gpiostate &= ~(1 << pin);
5835 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5836 AC_VERB_GET_GPIO_MASK, 0);
5837 gpiomask |= (1 << pin);
5839 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5840 AC_VERB_GET_GPIO_DIRECTION, 0);
5841 gpiodir |= (1 << pin);
5844 snd_hda_codec_write(codec, codec->afg, 0,
5845 AC_VERB_SET_GPIO_MASK, gpiomask);
5846 snd_hda_codec_write(codec, codec->afg, 0,
5847 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5851 snd_hda_codec_write(codec, codec->afg, 0,
5852 AC_VERB_SET_GPIO_DATA, gpiostate);
5855 /* set up GPIO at initialization */
5856 static void alc885_macpro_init_hook(struct hda_codec *codec)
5858 alc882_gpio_mute(codec, 0, 0);
5859 alc882_gpio_mute(codec, 1, 0);
5862 /* set up GPIO and update auto-muting at initialization */
5863 static void alc885_imac24_init_hook(struct hda_codec *codec)
5865 alc885_macpro_init_hook(codec);
5866 alc885_imac24_automute(codec);
5870 * generic initialization of ADC, input mixers and output mixers
5872 static struct hda_verb alc882_auto_init_verbs[] = {
5874 * Unmute ADC0-2 and set the default input to mic-in
5876 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5877 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5878 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5879 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5880 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5881 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5883 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5885 * Note: PASD motherboards uses the Line In 2 as the input for
5886 * front panel mic (mic 2)
5888 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5889 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5890 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5891 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5892 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5893 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5896 * Set up output mixers (0x0c - 0x0f)
5898 /* set vol=0 to output mixers */
5899 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5900 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5901 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5902 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5903 /* set up input amps for analog loopback */
5904 /* Amp Indices: DAC = 0, mixer = 1 */
5905 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5906 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5907 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5908 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5909 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5910 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5911 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5912 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5913 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5914 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5916 /* FIXME: use matrix-type input source selection */
5917 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5918 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5919 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5920 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5921 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5922 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5924 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5925 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5926 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5927 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5930 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5931 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5932 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5937 /* capture mixer elements */
5938 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5939 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5940 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5941 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5942 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5944 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5945 /* The multiple "Capture Source" controls confuse alsamixer
5946 * So call somewhat different..
5948 /* .name = "Capture Source", */
5949 .name = "Input Source",
5951 .info = alc882_mux_enum_info,
5952 .get = alc882_mux_enum_get,
5953 .put = alc882_mux_enum_put,
5958 static struct snd_kcontrol_new alc882_capture_mixer[] = {
5959 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5960 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5961 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5962 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5963 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5964 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5966 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5967 /* The multiple "Capture Source" controls confuse alsamixer
5968 * So call somewhat different..
5970 /* .name = "Capture Source", */
5971 .name = "Input Source",
5973 .info = alc882_mux_enum_info,
5974 .get = alc882_mux_enum_get,
5975 .put = alc882_mux_enum_put,
5980 #ifdef CONFIG_SND_HDA_POWER_SAVE
5981 #define alc882_loopbacks alc880_loopbacks
5984 /* pcm configuration: identiacal with ALC880 */
5985 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
5986 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
5987 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
5988 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
5991 * configuration and preset
5993 static const char *alc882_models[ALC882_MODEL_LAST] = {
5994 [ALC882_3ST_DIG] = "3stack-dig",
5995 [ALC882_6ST_DIG] = "6stack-dig",
5996 [ALC882_ARIMA] = "arima",
5997 [ALC882_W2JC] = "w2jc",
5998 [ALC882_TARGA] = "targa",
5999 [ALC882_ASUS_A7J] = "asus-a7j",
6000 [ALC882_ASUS_A7M] = "asus-a7m",
6001 [ALC885_MACPRO] = "macpro",
6002 [ALC885_MBP3] = "mbp3",
6003 [ALC885_IMAC24] = "imac24",
6004 [ALC882_AUTO] = "auto",
6007 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6008 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6009 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6010 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6011 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6012 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6013 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6014 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6015 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6016 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6017 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6018 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6019 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6023 static struct alc_config_preset alc882_presets[] = {
6024 [ALC882_3ST_DIG] = {
6025 .mixers = { alc882_base_mixer },
6026 .init_verbs = { alc882_init_verbs },
6027 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6028 .dac_nids = alc882_dac_nids,
6029 .dig_out_nid = ALC882_DIGOUT_NID,
6030 .dig_in_nid = ALC882_DIGIN_NID,
6031 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6032 .channel_mode = alc882_ch_modes,
6034 .input_mux = &alc882_capture_source,
6036 [ALC882_6ST_DIG] = {
6037 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6038 .init_verbs = { alc882_init_verbs },
6039 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6040 .dac_nids = alc882_dac_nids,
6041 .dig_out_nid = ALC882_DIGOUT_NID,
6042 .dig_in_nid = ALC882_DIGIN_NID,
6043 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6044 .channel_mode = alc882_sixstack_modes,
6045 .input_mux = &alc882_capture_source,
6048 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6049 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6050 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6051 .dac_nids = alc882_dac_nids,
6052 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6053 .channel_mode = alc882_sixstack_modes,
6054 .input_mux = &alc882_capture_source,
6057 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6058 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6059 alc880_gpio1_init_verbs },
6060 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6061 .dac_nids = alc882_dac_nids,
6062 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6063 .channel_mode = alc880_threestack_modes,
6065 .input_mux = &alc882_capture_source,
6066 .dig_out_nid = ALC882_DIGOUT_NID,
6069 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6070 .init_verbs = { alc885_mbp3_init_verbs,
6071 alc880_gpio1_init_verbs },
6072 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6073 .dac_nids = alc882_dac_nids,
6074 .channel_mode = alc885_mbp_6ch_modes,
6075 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6076 .input_mux = &alc882_capture_source,
6077 .dig_out_nid = ALC882_DIGOUT_NID,
6078 .dig_in_nid = ALC882_DIGIN_NID,
6079 .unsol_event = alc885_mbp3_unsol_event,
6080 .init_hook = alc885_mbp3_automute,
6083 .mixers = { alc882_macpro_mixer },
6084 .init_verbs = { alc882_macpro_init_verbs },
6085 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6086 .dac_nids = alc882_dac_nids,
6087 .dig_out_nid = ALC882_DIGOUT_NID,
6088 .dig_in_nid = ALC882_DIGIN_NID,
6089 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6090 .channel_mode = alc882_ch_modes,
6091 .input_mux = &alc882_capture_source,
6092 .init_hook = alc885_macpro_init_hook,
6095 .mixers = { alc885_imac24_mixer },
6096 .init_verbs = { alc885_imac24_init_verbs },
6097 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6098 .dac_nids = alc882_dac_nids,
6099 .dig_out_nid = ALC882_DIGOUT_NID,
6100 .dig_in_nid = ALC882_DIGIN_NID,
6101 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6102 .channel_mode = alc882_ch_modes,
6103 .input_mux = &alc882_capture_source,
6104 .unsol_event = alc885_imac24_unsol_event,
6105 .init_hook = alc885_imac24_init_hook,
6108 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6109 alc882_capture_mixer },
6110 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6111 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6112 .dac_nids = alc882_dac_nids,
6113 .dig_out_nid = ALC882_DIGOUT_NID,
6114 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6115 .adc_nids = alc882_adc_nids,
6116 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6117 .channel_mode = alc882_3ST_6ch_modes,
6119 .input_mux = &alc882_capture_source,
6120 .unsol_event = alc882_targa_unsol_event,
6121 .init_hook = alc882_targa_automute,
6123 [ALC882_ASUS_A7J] = {
6124 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6125 alc882_capture_mixer },
6126 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6127 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6128 .dac_nids = alc882_dac_nids,
6129 .dig_out_nid = ALC882_DIGOUT_NID,
6130 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6131 .adc_nids = alc882_adc_nids,
6132 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6133 .channel_mode = alc882_3ST_6ch_modes,
6135 .input_mux = &alc882_capture_source,
6137 [ALC882_ASUS_A7M] = {
6138 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6139 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6140 alc880_gpio1_init_verbs,
6141 alc882_asus_a7m_verbs },
6142 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6143 .dac_nids = alc882_dac_nids,
6144 .dig_out_nid = ALC882_DIGOUT_NID,
6145 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6146 .channel_mode = alc880_threestack_modes,
6148 .input_mux = &alc882_capture_source,
6157 PINFIX_ABIT_AW9D_MAX
6160 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6161 { 0x15, 0x01080104 }, /* side */
6162 { 0x16, 0x01011012 }, /* rear */
6163 { 0x17, 0x01016011 }, /* clfe */
6167 static const struct alc_pincfg *alc882_pin_fixes[] = {
6168 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6171 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6172 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6177 * BIOS auto configuration
6179 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6180 hda_nid_t nid, int pin_type,
6184 struct alc_spec *spec = codec->spec;
6187 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6190 idx = spec->multiout.dac_nids[dac_idx] - 2;
6192 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6194 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
6196 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6200 static void alc882_auto_init_multi_out(struct hda_codec *codec)
6202 struct alc_spec *spec = codec->spec;
6205 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6206 for (i = 0; i <= HDA_SIDE; i++) {
6207 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6208 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6210 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6215 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6217 struct alc_spec *spec = codec->spec;
6220 pin = spec->autocfg.hp_pins[0];
6221 if (pin) /* connect to front */
6223 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6226 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6227 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6229 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6231 struct alc_spec *spec = codec->spec;
6234 for (i = 0; i < AUTO_PIN_LAST; i++) {
6235 hda_nid_t nid = spec->autocfg.input_pins[i];
6236 if (alc882_is_input_pin(nid)) {
6237 snd_hda_codec_write(codec, nid, 0,
6238 AC_VERB_SET_PIN_WIDGET_CONTROL,
6239 i <= AUTO_PIN_FRONT_MIC ?
6240 PIN_VREF80 : PIN_IN);
6241 if (nid != ALC882_PIN_CD_NID)
6242 snd_hda_codec_write(codec, nid, 0,
6243 AC_VERB_SET_AMP_GAIN_MUTE,
6249 /* add mic boosts if needed */
6250 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6252 struct alc_spec *spec = codec->spec;
6256 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6257 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6258 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6260 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6264 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6265 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6266 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6268 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6275 /* almost identical with ALC880 parser... */
6276 static int alc882_parse_auto_config(struct hda_codec *codec)
6278 struct alc_spec *spec = codec->spec;
6279 int err = alc880_parse_auto_config(codec);
6284 return 0; /* no config found */
6286 err = alc_auto_add_mic_boost(codec);
6290 /* hack - override the init verbs */
6291 spec->init_verbs[0] = alc882_auto_init_verbs;
6293 return 1; /* config found */
6296 /* additional initialization for auto-configuration model */
6297 static void alc882_auto_init(struct hda_codec *codec)
6299 alc882_auto_init_multi_out(codec);
6300 alc882_auto_init_hp_out(codec);
6301 alc882_auto_init_analog_input(codec);
6304 static int patch_alc882(struct hda_codec *codec)
6306 struct alc_spec *spec;
6307 int err, board_config;
6309 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6315 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6319 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6320 /* Pick up systems that don't supply PCI SSID */
6321 switch (codec->subsystem_id) {
6322 case 0x106b0c00: /* Mac Pro */
6323 board_config = ALC885_MACPRO;
6325 case 0x106b1000: /* iMac 24 */
6326 board_config = ALC885_IMAC24;
6328 case 0x106b00a1: /* Macbook */
6329 case 0x106b2c00: /* Macbook Pro rev3 */
6330 board_config = ALC885_MBP3;
6333 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6334 "trying auto-probe from BIOS...\n");
6335 board_config = ALC882_AUTO;
6339 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6341 if (board_config == ALC882_AUTO) {
6342 /* automatic parse from the BIOS config */
6343 err = alc882_parse_auto_config(codec);
6349 "hda_codec: Cannot set up configuration "
6350 "from BIOS. Using base mode...\n");
6351 board_config = ALC882_3ST_DIG;
6355 if (board_config != ALC882_AUTO)
6356 setup_preset(spec, &alc882_presets[board_config]);
6358 spec->stream_name_analog = "ALC882 Analog";
6359 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6360 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6361 /* FIXME: setup DAC5 */
6362 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6363 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6365 spec->stream_name_digital = "ALC882 Digital";
6366 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6367 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6369 if (!spec->adc_nids && spec->input_mux) {
6370 /* check whether NID 0x07 is valid */
6371 unsigned int wcap = get_wcaps(codec, 0x07);
6373 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6374 if (wcap != AC_WID_AUD_IN) {
6375 spec->adc_nids = alc882_adc_nids_alt;
6376 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6377 spec->mixers[spec->num_mixers] =
6378 alc882_capture_alt_mixer;
6381 spec->adc_nids = alc882_adc_nids;
6382 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6383 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6388 spec->vmaster_nid = 0x0c;
6390 codec->patch_ops = alc_patch_ops;
6391 if (board_config == ALC882_AUTO)
6392 spec->init_hook = alc882_auto_init;
6393 #ifdef CONFIG_SND_HDA_POWER_SAVE
6394 if (!spec->loopback.amplist)
6395 spec->loopback.amplist = alc882_loopbacks;
6404 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6405 * configuration. Each pin widget can choose any input DACs and a mixer.
6406 * Each ADC is connected from a mixer of all inputs. This makes possible
6407 * 6-channel independent captures.
6409 * In addition, an independent DAC for the multi-playback (not used in this
6412 #define ALC883_DIGOUT_NID 0x06
6413 #define ALC883_DIGIN_NID 0x0a
6415 static hda_nid_t alc883_dac_nids[4] = {
6416 /* front, rear, clfe, rear_surr */
6417 0x02, 0x04, 0x03, 0x05
6420 static hda_nid_t alc883_adc_nids[2] = {
6426 /* FIXME: should be a matrix-type input source selection */
6428 static struct hda_input_mux alc883_capture_source = {
6432 { "Front Mic", 0x1 },
6438 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6446 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6456 #define alc883_mux_enum_info alc_mux_enum_info
6457 #define alc883_mux_enum_get alc_mux_enum_get
6459 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
6460 struct snd_ctl_elem_value *ucontrol)
6462 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6463 struct alc_spec *spec = codec->spec;
6464 const struct hda_input_mux *imux = spec->input_mux;
6465 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
6466 static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
6467 hda_nid_t nid = capture_mixers[adc_idx];
6468 unsigned int *cur_val = &spec->cur_mux[adc_idx];
6469 unsigned int i, idx;
6471 idx = ucontrol->value.enumerated.item[0];
6472 if (idx >= imux->num_items)
6473 idx = imux->num_items - 1;
6474 if (*cur_val == idx)
6476 for (i = 0; i < imux->num_items; i++) {
6477 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
6478 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
6479 imux->items[i].index,
6489 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6496 static struct hda_verb alc883_3ST_ch2_init[] = {
6497 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6498 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6499 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6500 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6507 static struct hda_verb alc883_3ST_ch4_init[] = {
6508 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6509 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6510 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6511 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6512 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6519 static struct hda_verb alc883_3ST_ch6_init[] = {
6520 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6521 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6522 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6523 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6524 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6525 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6529 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6530 { 2, alc883_3ST_ch2_init },
6531 { 4, alc883_3ST_ch4_init },
6532 { 6, alc883_3ST_ch6_init },
6538 static struct hda_verb alc883_sixstack_ch6_init[] = {
6539 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6540 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6541 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6542 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6549 static struct hda_verb alc883_sixstack_ch8_init[] = {
6550 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6551 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6552 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6553 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6557 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6558 { 6, alc883_sixstack_ch6_init },
6559 { 8, alc883_sixstack_ch8_init },
6562 static struct hda_verb alc883_medion_eapd_verbs[] = {
6563 /* eanable EAPD on medion laptop */
6564 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6565 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6569 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6570 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6573 static struct snd_kcontrol_new alc883_base_mixer[] = {
6574 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6575 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6576 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6577 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6578 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6579 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6580 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6581 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6582 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6583 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6584 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6585 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6586 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6587 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6588 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6589 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6590 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6591 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6592 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6593 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6594 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6595 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6596 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6597 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6598 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6599 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6600 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6602 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6603 /* .name = "Capture Source", */
6604 .name = "Input Source",
6606 .info = alc883_mux_enum_info,
6607 .get = alc883_mux_enum_get,
6608 .put = alc883_mux_enum_put,
6613 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6614 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6615 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6616 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6617 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6618 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6619 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6620 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6621 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6622 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6623 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6624 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6625 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6626 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6627 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6628 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6629 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6630 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6632 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6633 /* .name = "Capture Source", */
6634 .name = "Input Source",
6636 .info = alc883_mux_enum_info,
6637 .get = alc883_mux_enum_get,
6638 .put = alc883_mux_enum_put,
6643 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6644 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6645 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6646 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6647 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6648 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6649 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6650 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6651 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6652 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6653 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6654 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6655 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6656 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6657 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6658 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6659 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6660 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6661 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6662 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6664 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6665 /* .name = "Capture Source", */
6666 .name = "Input Source",
6668 .info = alc883_mux_enum_info,
6669 .get = alc883_mux_enum_get,
6670 .put = alc883_mux_enum_put,
6675 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6676 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6677 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6678 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6679 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6680 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6681 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6682 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6683 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6684 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6685 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6686 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6687 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6688 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6689 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6690 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6691 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6692 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6693 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6694 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6695 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6696 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6697 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6698 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6699 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6700 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6703 /* .name = "Capture Source", */
6704 .name = "Input Source",
6706 .info = alc883_mux_enum_info,
6707 .get = alc883_mux_enum_get,
6708 .put = alc883_mux_enum_put,
6713 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6714 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6715 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6716 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6717 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6718 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6719 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6720 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6721 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6722 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6723 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6724 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6725 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6726 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6727 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6728 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6729 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6730 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6731 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6732 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6733 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6734 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6735 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6736 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6739 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6740 /* .name = "Capture Source", */
6741 .name = "Input Source",
6743 .info = alc883_mux_enum_info,
6744 .get = alc883_mux_enum_get,
6745 .put = alc883_mux_enum_put,
6750 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6751 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6752 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6753 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6754 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6755 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6756 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6757 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6758 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6759 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6760 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6761 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6762 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6763 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6764 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6765 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6766 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6767 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6768 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6769 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6770 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6772 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6773 /* .name = "Capture Source", */
6774 .name = "Input Source",
6776 .info = alc883_mux_enum_info,
6777 .get = alc883_mux_enum_get,
6778 .put = alc883_mux_enum_put,
6783 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6784 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6785 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6786 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6787 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6788 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6789 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6790 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6791 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6792 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6793 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6794 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6795 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6797 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6798 /* .name = "Capture Source", */
6799 .name = "Input Source",
6801 .info = alc883_mux_enum_info,
6802 .get = alc883_mux_enum_get,
6803 .put = alc883_mux_enum_put,
6808 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6809 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6810 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6811 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6812 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
6813 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6814 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6815 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6816 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6817 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6818 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6820 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6821 /* .name = "Capture Source", */
6822 .name = "Input Source",
6824 .info = alc883_mux_enum_info,
6825 .get = alc883_mux_enum_get,
6826 .put = alc883_mux_enum_put,
6831 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6832 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6833 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6834 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6835 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6836 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6837 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6838 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6839 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6840 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6841 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6842 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6843 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6844 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6846 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6847 /* .name = "Capture Source", */
6848 .name = "Input Source",
6850 .info = alc883_mux_enum_info,
6851 .get = alc883_mux_enum_get,
6852 .put = alc883_mux_enum_put,
6857 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6858 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6859 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6860 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6861 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6862 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6863 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6864 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6865 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6866 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6867 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6868 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6869 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6870 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6872 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6873 /* .name = "Capture Source", */
6874 .name = "Input Source",
6876 .info = alc883_mux_enum_info,
6877 .get = alc883_mux_enum_get,
6878 .put = alc883_mux_enum_put,
6883 static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6884 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6885 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6886 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6887 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6888 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6889 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6890 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6891 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6892 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6893 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6894 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6895 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6896 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6897 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6898 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6899 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6900 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6901 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6902 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6903 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6904 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6905 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6906 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6907 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6908 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6909 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6910 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6912 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6913 /* .name = "Capture Source", */
6914 .name = "Input Source",
6916 .info = alc883_mux_enum_info,
6917 .get = alc883_mux_enum_get,
6918 .put = alc883_mux_enum_put,
6923 static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6924 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6925 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6926 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6927 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6928 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6929 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6930 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6931 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6932 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6933 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6934 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6935 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6936 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6937 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6938 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6939 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6940 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6941 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6942 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6943 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6944 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6945 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6946 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6947 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6948 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6950 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6951 /* .name = "Capture Source", */
6952 .name = "Input Source",
6954 .info = alc883_mux_enum_info,
6955 .get = alc883_mux_enum_get,
6956 .put = alc883_mux_enum_put,
6961 static struct snd_kcontrol_new alc888_6st_dell_mixer[] = {
6962 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6963 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6964 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6965 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6966 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6967 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6968 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6969 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6970 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6971 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6972 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6973 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6974 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6975 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6976 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6977 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6978 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6979 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6980 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6981 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6982 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6983 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6984 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6985 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6986 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6987 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6988 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6990 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6991 /* .name = "Capture Source", */
6992 .name = "Input Source",
6994 .info = alc883_mux_enum_info,
6995 .get = alc883_mux_enum_get,
6996 .put = alc883_mux_enum_put,
7001 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7002 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7003 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7004 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7005 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7006 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7007 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7008 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7009 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7010 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7011 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7012 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7013 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7016 /* .name = "Capture Source", */
7017 .name = "Input Source",
7019 .info = alc883_mux_enum_info,
7020 .get = alc883_mux_enum_get,
7021 .put = alc883_mux_enum_put,
7026 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7028 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7029 .name = "Channel Mode",
7030 .info = alc_ch_mode_info,
7031 .get = alc_ch_mode_get,
7032 .put = alc_ch_mode_put,
7037 static struct hda_verb alc883_init_verbs[] = {
7038 /* ADC1: mute amp left and right */
7039 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7040 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7041 /* ADC2: mute amp left and right */
7042 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7043 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7044 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7045 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7046 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7047 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7049 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7050 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7051 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7053 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7054 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7055 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7057 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7058 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7059 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7061 /* mute analog input loopbacks */
7062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7065 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7066 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7068 /* Front Pin: output 0 (0x0c) */
7069 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7070 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7071 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7072 /* Rear Pin: output 1 (0x0d) */
7073 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7074 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7075 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7076 /* CLFE Pin: output 2 (0x0e) */
7077 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7078 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7079 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7080 /* Side Pin: output 3 (0x0f) */
7081 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7082 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7083 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7084 /* Mic (rear) pin: input vref at 80% */
7085 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7086 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7087 /* Front Mic pin: input vref at 80% */
7088 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7089 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7090 /* Line In pin: input */
7091 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7092 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7093 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7094 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7095 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7096 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7097 /* CD pin widget for input */
7098 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7100 /* FIXME: use matrix-type input source selection */
7101 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7103 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7104 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7105 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7106 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7108 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7109 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7110 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7111 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7115 /* toggle speaker-output according to the hp-jack state */
7116 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7118 unsigned int present;
7120 present = snd_hda_codec_read(codec, 0x15, 0,
7121 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7122 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7123 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7124 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7125 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7128 /* auto-toggle front mic */
7130 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7132 unsigned int present;
7135 present = snd_hda_codec_read(codec, 0x18, 0,
7136 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7137 bits = present ? HDA_AMP_MUTE : 0;
7138 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7142 static void alc883_mitac_automute(struct hda_codec *codec)
7144 alc883_mitac_hp_automute(codec);
7145 /* alc883_mitac_mic_automute(codec); */
7148 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7151 switch (res >> 26) {
7152 case ALC880_HP_EVENT:
7153 alc883_mitac_hp_automute(codec);
7155 case ALC880_MIC_EVENT:
7156 /* alc883_mitac_mic_automute(codec); */
7161 static struct hda_verb alc883_mitac_verbs[] = {
7163 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7164 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7166 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7167 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7169 /* enable unsolicited event */
7170 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7171 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7176 static struct hda_verb alc883_tagra_verbs[] = {
7177 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7178 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7180 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7181 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7183 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7184 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7185 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7187 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7188 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7189 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7190 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7195 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7196 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7197 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7198 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7202 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7203 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7205 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7206 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7210 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7211 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7212 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7213 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7214 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7215 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7219 static struct hda_verb alc883_haier_w66_verbs[] = {
7220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7223 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7225 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7226 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7227 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7228 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7232 static struct hda_verb alc888_6st_hp_verbs[] = {
7233 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7234 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */
7235 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */
7236 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
7240 static struct hda_verb alc888_3st_hp_verbs[] = {
7241 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7242 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7243 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7247 static struct hda_verb alc888_6st_dell_verbs[] = {
7248 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7249 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 1 (0x0e) */
7250 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 2 (0x0d) */
7251 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
7252 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7256 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7257 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7258 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7259 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7260 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7264 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7265 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7266 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7267 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7268 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7272 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7273 { 2, alc888_3st_hp_2ch_init },
7274 { 6, alc888_3st_hp_6ch_init },
7277 /* toggle front-jack and RCA according to the hp-jack state */
7278 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7280 unsigned int present;
7282 present = snd_hda_codec_read(codec, 0x1b, 0,
7283 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7284 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7285 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7286 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7287 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7290 /* toggle RCA according to the front-jack state */
7291 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7293 unsigned int present;
7295 present = snd_hda_codec_read(codec, 0x14, 0,
7296 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7297 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7298 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7301 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7304 if ((res >> 26) == ALC880_HP_EVENT)
7305 alc888_lenovo_ms7195_front_automute(codec);
7306 if ((res >> 26) == ALC880_FRONT_EVENT)
7307 alc888_lenovo_ms7195_rca_automute(codec);
7310 static struct hda_verb alc883_medion_md2_verbs[] = {
7311 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7314 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7316 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7320 /* toggle speaker-output according to the hp-jack state */
7321 static void alc883_medion_md2_automute(struct hda_codec *codec)
7323 unsigned int present;
7325 present = snd_hda_codec_read(codec, 0x14, 0,
7326 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7327 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7328 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7331 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7334 if ((res >> 26) == ALC880_HP_EVENT)
7335 alc883_medion_md2_automute(codec);
7338 /* toggle speaker-output according to the hp-jack state */
7339 static void alc883_tagra_automute(struct hda_codec *codec)
7341 unsigned int present;
7344 present = snd_hda_codec_read(codec, 0x14, 0,
7345 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7346 bits = present ? HDA_AMP_MUTE : 0;
7347 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7348 HDA_AMP_MUTE, bits);
7349 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7353 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7355 if ((res >> 26) == ALC880_HP_EVENT)
7356 alc883_tagra_automute(codec);
7359 static void alc883_haier_w66_automute(struct hda_codec *codec)
7361 unsigned int present;
7364 present = snd_hda_codec_read(codec, 0x1b, 0,
7365 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7366 bits = present ? 0x80 : 0;
7367 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7371 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7374 if ((res >> 26) == ALC880_HP_EVENT)
7375 alc883_haier_w66_automute(codec);
7378 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7380 unsigned int present;
7383 present = snd_hda_codec_read(codec, 0x14, 0,
7384 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7385 bits = present ? HDA_AMP_MUTE : 0;
7386 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7387 HDA_AMP_MUTE, bits);
7390 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7392 unsigned int present;
7395 present = snd_hda_codec_read(codec, 0x1b, 0,
7396 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7397 bits = present ? HDA_AMP_MUTE : 0;
7398 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7399 HDA_AMP_MUTE, bits);
7400 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7401 HDA_AMP_MUTE, bits);
7404 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7407 if ((res >> 26) == ALC880_HP_EVENT)
7408 alc883_lenovo_101e_all_automute(codec);
7409 if ((res >> 26) == ALC880_FRONT_EVENT)
7410 alc883_lenovo_101e_ispeaker_automute(codec);
7413 /* toggle speaker-output according to the hp-jack state */
7414 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7416 unsigned int present;
7418 present = snd_hda_codec_read(codec, 0x14, 0,
7419 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7420 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7421 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7422 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7423 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7426 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7429 if ((res >> 26) == ALC880_HP_EVENT)
7430 alc883_acer_aspire_automute(codec);
7433 static struct hda_verb alc883_acer_eapd_verbs[] = {
7434 /* HP Pin: output 0 (0x0c) */
7435 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7436 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7437 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7438 /* Front Pin: output 0 (0x0c) */
7439 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7440 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7441 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7442 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7443 /* eanable EAPD on medion laptop */
7444 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7445 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7446 /* enable unsolicited event */
7447 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7451 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7453 unsigned int present;
7455 present = snd_hda_codec_read(codec, 0x1b, 0,
7456 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7457 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7458 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7459 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7460 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7461 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7462 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7463 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7464 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7467 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7470 switch (res >> 26) {
7471 case ALC880_HP_EVENT:
7472 printk("hp_event\n");
7473 alc888_6st_dell_front_automute(codec);
7479 * generic initialization of ADC, input mixers and output mixers
7481 static struct hda_verb alc883_auto_init_verbs[] = {
7483 * Unmute ADC0-2 and set the default input to mic-in
7485 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7486 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7487 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7490 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7492 * Note: PASD motherboards uses the Line In 2 as the input for
7493 * front panel mic (mic 2)
7495 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7496 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7497 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7498 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7499 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7500 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7503 * Set up output mixers (0x0c - 0x0f)
7505 /* set vol=0 to output mixers */
7506 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7507 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7508 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7509 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7510 /* set up input amps for analog loopback */
7511 /* Amp Indices: DAC = 0, mixer = 1 */
7512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7513 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7515 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7517 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7518 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7519 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7520 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7521 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7523 /* FIXME: use matrix-type input source selection */
7524 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7528 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7529 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7535 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7541 /* capture mixer elements */
7542 static struct snd_kcontrol_new alc883_capture_mixer[] = {
7543 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7544 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7545 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7546 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7548 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7549 /* The multiple "Capture Source" controls confuse alsamixer
7550 * So call somewhat different..
7552 /* .name = "Capture Source", */
7553 .name = "Input Source",
7555 .info = alc882_mux_enum_info,
7556 .get = alc882_mux_enum_get,
7557 .put = alc882_mux_enum_put,
7562 #ifdef CONFIG_SND_HDA_POWER_SAVE
7563 #define alc883_loopbacks alc880_loopbacks
7566 /* pcm configuration: identiacal with ALC880 */
7567 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
7568 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
7569 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
7570 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
7571 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
7574 * configuration and preset
7576 static const char *alc883_models[ALC883_MODEL_LAST] = {
7577 [ALC883_3ST_2ch_DIG] = "3stack-dig",
7578 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
7579 [ALC883_3ST_6ch] = "3stack-6ch",
7580 [ALC883_6ST_DIG] = "6stack-dig",
7581 [ALC883_TARGA_DIG] = "targa-dig",
7582 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
7583 [ALC883_ACER] = "acer",
7584 [ALC883_ACER_ASPIRE] = "acer-aspire",
7585 [ALC883_MEDION] = "medion",
7586 [ALC883_MEDION_MD2] = "medion-md2",
7587 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
7588 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
7589 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
7590 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
7591 [ALC883_HAIER_W66] = "haier-w66",
7592 [ALC888_6ST_HP] = "6stack-hp",
7593 [ALC888_3ST_HP] = "3stack-hp",
7594 [ALC888_6ST_DELL] = "6stack-dell",
7595 [ALC883_MITAC] = "mitac",
7596 [ALC883_AUTO] = "auto",
7599 static struct snd_pci_quirk alc883_cfg_tbl[] = {
7600 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
7601 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7602 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7603 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7604 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
7605 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
7606 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
7607 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7608 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7609 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7610 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
7611 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
7612 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7613 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7614 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
7615 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
7616 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
7617 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
7618 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
7619 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
7620 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
7621 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
7622 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7623 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
7624 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
7625 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
7626 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7627 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7628 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
7629 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7630 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7631 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7632 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7633 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
7634 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
7635 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7636 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
7637 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
7638 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
7639 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
7640 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7641 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7642 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7643 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7644 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
7645 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
7646 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
7650 static struct alc_config_preset alc883_presets[] = {
7651 [ALC883_3ST_2ch_DIG] = {
7652 .mixers = { alc883_3ST_2ch_mixer },
7653 .init_verbs = { alc883_init_verbs },
7654 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7655 .dac_nids = alc883_dac_nids,
7656 .dig_out_nid = ALC883_DIGOUT_NID,
7657 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7658 .adc_nids = alc883_adc_nids,
7659 .dig_in_nid = ALC883_DIGIN_NID,
7660 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7661 .channel_mode = alc883_3ST_2ch_modes,
7662 .input_mux = &alc883_capture_source,
7664 [ALC883_3ST_6ch_DIG] = {
7665 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7666 .init_verbs = { alc883_init_verbs },
7667 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7668 .dac_nids = alc883_dac_nids,
7669 .dig_out_nid = ALC883_DIGOUT_NID,
7670 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7671 .adc_nids = alc883_adc_nids,
7672 .dig_in_nid = ALC883_DIGIN_NID,
7673 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7674 .channel_mode = alc883_3ST_6ch_modes,
7676 .input_mux = &alc883_capture_source,
7678 [ALC883_3ST_6ch] = {
7679 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7680 .init_verbs = { alc883_init_verbs },
7681 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7682 .dac_nids = alc883_dac_nids,
7683 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7684 .adc_nids = alc883_adc_nids,
7685 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7686 .channel_mode = alc883_3ST_6ch_modes,
7688 .input_mux = &alc883_capture_source,
7690 [ALC883_6ST_DIG] = {
7691 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7692 .init_verbs = { alc883_init_verbs },
7693 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7694 .dac_nids = alc883_dac_nids,
7695 .dig_out_nid = ALC883_DIGOUT_NID,
7696 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7697 .adc_nids = alc883_adc_nids,
7698 .dig_in_nid = ALC883_DIGIN_NID,
7699 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7700 .channel_mode = alc883_sixstack_modes,
7701 .input_mux = &alc883_capture_source,
7703 [ALC883_TARGA_DIG] = {
7704 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7705 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7706 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7707 .dac_nids = alc883_dac_nids,
7708 .dig_out_nid = ALC883_DIGOUT_NID,
7709 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7710 .adc_nids = alc883_adc_nids,
7711 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7712 .channel_mode = alc883_3ST_6ch_modes,
7714 .input_mux = &alc883_capture_source,
7715 .unsol_event = alc883_tagra_unsol_event,
7716 .init_hook = alc883_tagra_automute,
7718 [ALC883_TARGA_2ch_DIG] = {
7719 .mixers = { alc883_tagra_2ch_mixer},
7720 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7721 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7722 .dac_nids = alc883_dac_nids,
7723 .dig_out_nid = ALC883_DIGOUT_NID,
7724 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7725 .adc_nids = alc883_adc_nids,
7726 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7727 .channel_mode = alc883_3ST_2ch_modes,
7728 .input_mux = &alc883_capture_source,
7729 .unsol_event = alc883_tagra_unsol_event,
7730 .init_hook = alc883_tagra_automute,
7733 .mixers = { alc883_base_mixer },
7734 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7735 * and the headphone jack. Turn this on and rely on the
7736 * standard mute methods whenever the user wants to turn
7737 * these outputs off.
7739 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7740 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7741 .dac_nids = alc883_dac_nids,
7742 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7743 .adc_nids = alc883_adc_nids,
7744 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7745 .channel_mode = alc883_3ST_2ch_modes,
7746 .input_mux = &alc883_capture_source,
7748 [ALC883_ACER_ASPIRE] = {
7749 .mixers = { alc883_acer_aspire_mixer },
7750 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
7751 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7752 .dac_nids = alc883_dac_nids,
7753 .dig_out_nid = ALC883_DIGOUT_NID,
7754 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7755 .adc_nids = alc883_adc_nids,
7756 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7757 .channel_mode = alc883_3ST_2ch_modes,
7758 .input_mux = &alc883_capture_source,
7759 .unsol_event = alc883_acer_aspire_unsol_event,
7760 .init_hook = alc883_acer_aspire_automute,
7763 .mixers = { alc883_fivestack_mixer,
7764 alc883_chmode_mixer },
7765 .init_verbs = { alc883_init_verbs,
7766 alc883_medion_eapd_verbs },
7767 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7768 .dac_nids = alc883_dac_nids,
7769 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7770 .adc_nids = alc883_adc_nids,
7771 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7772 .channel_mode = alc883_sixstack_modes,
7773 .input_mux = &alc883_capture_source,
7775 [ALC883_MEDION_MD2] = {
7776 .mixers = { alc883_medion_md2_mixer},
7777 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7778 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7779 .dac_nids = alc883_dac_nids,
7780 .dig_out_nid = ALC883_DIGOUT_NID,
7781 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7782 .adc_nids = alc883_adc_nids,
7783 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7784 .channel_mode = alc883_3ST_2ch_modes,
7785 .input_mux = &alc883_capture_source,
7786 .unsol_event = alc883_medion_md2_unsol_event,
7787 .init_hook = alc883_medion_md2_automute,
7789 [ALC883_LAPTOP_EAPD] = {
7790 .mixers = { alc883_base_mixer },
7791 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7792 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7793 .dac_nids = alc883_dac_nids,
7794 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7795 .adc_nids = alc883_adc_nids,
7796 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7797 .channel_mode = alc883_3ST_2ch_modes,
7798 .input_mux = &alc883_capture_source,
7800 [ALC883_LENOVO_101E_2ch] = {
7801 .mixers = { alc883_lenovo_101e_2ch_mixer},
7802 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7803 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7804 .dac_nids = alc883_dac_nids,
7805 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7806 .adc_nids = alc883_adc_nids,
7807 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7808 .channel_mode = alc883_3ST_2ch_modes,
7809 .input_mux = &alc883_lenovo_101e_capture_source,
7810 .unsol_event = alc883_lenovo_101e_unsol_event,
7811 .init_hook = alc883_lenovo_101e_all_automute,
7813 [ALC883_LENOVO_NB0763] = {
7814 .mixers = { alc883_lenovo_nb0763_mixer },
7815 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7816 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7817 .dac_nids = alc883_dac_nids,
7818 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7819 .adc_nids = alc883_adc_nids,
7820 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7821 .channel_mode = alc883_3ST_2ch_modes,
7823 .input_mux = &alc883_lenovo_nb0763_capture_source,
7824 .unsol_event = alc883_medion_md2_unsol_event,
7825 .init_hook = alc883_medion_md2_automute,
7827 [ALC888_LENOVO_MS7195_DIG] = {
7828 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7829 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7830 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7831 .dac_nids = alc883_dac_nids,
7832 .dig_out_nid = ALC883_DIGOUT_NID,
7833 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7834 .adc_nids = alc883_adc_nids,
7835 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7836 .channel_mode = alc883_3ST_6ch_modes,
7838 .input_mux = &alc883_capture_source,
7839 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7840 .init_hook = alc888_lenovo_ms7195_front_automute,
7842 [ALC883_HAIER_W66] = {
7843 .mixers = { alc883_tagra_2ch_mixer},
7844 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7845 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7846 .dac_nids = alc883_dac_nids,
7847 .dig_out_nid = ALC883_DIGOUT_NID,
7848 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7849 .adc_nids = alc883_adc_nids,
7850 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7851 .channel_mode = alc883_3ST_2ch_modes,
7852 .input_mux = &alc883_capture_source,
7853 .unsol_event = alc883_haier_w66_unsol_event,
7854 .init_hook = alc883_haier_w66_automute,
7857 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7858 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
7859 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7860 .dac_nids = alc883_dac_nids,
7861 .dig_out_nid = ALC883_DIGOUT_NID,
7862 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7863 .adc_nids = alc883_adc_nids,
7864 .dig_in_nid = ALC883_DIGIN_NID,
7865 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7866 .channel_mode = alc883_sixstack_modes,
7867 .input_mux = &alc883_capture_source,
7870 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7871 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
7872 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7873 .dac_nids = alc883_dac_nids,
7874 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7875 .adc_nids = alc883_adc_nids,
7876 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7877 .channel_mode = alc888_3st_hp_modes,
7879 .input_mux = &alc883_capture_source,
7881 [ALC888_6ST_DELL] = {
7882 .mixers = { alc888_6st_dell_mixer, alc883_chmode_mixer },
7883 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
7884 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7885 .dac_nids = alc883_dac_nids,
7886 .dig_out_nid = ALC883_DIGOUT_NID,
7887 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7888 .adc_nids = alc883_adc_nids,
7889 .dig_in_nid = ALC883_DIGIN_NID,
7890 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7891 .channel_mode = alc883_sixstack_modes,
7892 .input_mux = &alc883_capture_source,
7893 .unsol_event = alc888_6st_dell_unsol_event,
7894 .init_hook = alc888_6st_dell_front_automute,
7897 .mixers = { alc883_mitac_mixer },
7898 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
7899 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7900 .dac_nids = alc883_dac_nids,
7901 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7902 .adc_nids = alc883_adc_nids,
7903 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7904 .channel_mode = alc883_3ST_2ch_modes,
7905 .input_mux = &alc883_capture_source,
7906 .unsol_event = alc883_mitac_unsol_event,
7907 .init_hook = alc883_mitac_automute,
7913 * BIOS auto configuration
7915 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7916 hda_nid_t nid, int pin_type,
7920 struct alc_spec *spec = codec->spec;
7923 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7926 idx = spec->multiout.dac_nids[dac_idx] - 2;
7928 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7930 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7932 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7936 static void alc883_auto_init_multi_out(struct hda_codec *codec)
7938 struct alc_spec *spec = codec->spec;
7941 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7942 for (i = 0; i <= HDA_SIDE; i++) {
7943 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7944 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7946 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
7951 static void alc883_auto_init_hp_out(struct hda_codec *codec)
7953 struct alc_spec *spec = codec->spec;
7956 pin = spec->autocfg.hp_pins[0];
7957 if (pin) /* connect to front */
7959 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7962 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
7963 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
7965 static void alc883_auto_init_analog_input(struct hda_codec *codec)
7967 struct alc_spec *spec = codec->spec;
7970 for (i = 0; i < AUTO_PIN_LAST; i++) {
7971 hda_nid_t nid = spec->autocfg.input_pins[i];
7972 if (alc883_is_input_pin(nid)) {
7973 snd_hda_codec_write(codec, nid, 0,
7974 AC_VERB_SET_PIN_WIDGET_CONTROL,
7975 (i <= AUTO_PIN_FRONT_MIC ?
7976 PIN_VREF80 : PIN_IN));
7977 if (nid != ALC883_PIN_CD_NID)
7978 snd_hda_codec_write(codec, nid, 0,
7979 AC_VERB_SET_AMP_GAIN_MUTE,
7985 /* almost identical with ALC880 parser... */
7986 static int alc883_parse_auto_config(struct hda_codec *codec)
7988 struct alc_spec *spec = codec->spec;
7989 int err = alc880_parse_auto_config(codec);
7994 return 0; /* no config found */
7996 err = alc_auto_add_mic_boost(codec);
8000 /* hack - override the init verbs */
8001 spec->init_verbs[0] = alc883_auto_init_verbs;
8002 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8005 return 1; /* config found */
8008 /* additional initialization for auto-configuration model */
8009 static void alc883_auto_init(struct hda_codec *codec)
8011 alc883_auto_init_multi_out(codec);
8012 alc883_auto_init_hp_out(codec);
8013 alc883_auto_init_analog_input(codec);
8016 static int patch_alc883(struct hda_codec *codec)
8018 struct alc_spec *spec;
8019 int err, board_config;
8021 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8027 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8030 if (board_config < 0) {
8031 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8032 "trying auto-probe from BIOS...\n");
8033 board_config = ALC883_AUTO;
8036 if (board_config == ALC883_AUTO) {
8037 /* automatic parse from the BIOS config */
8038 err = alc883_parse_auto_config(codec);
8044 "hda_codec: Cannot set up configuration "
8045 "from BIOS. Using base mode...\n");
8046 board_config = ALC883_3ST_2ch_DIG;
8050 if (board_config != ALC883_AUTO)
8051 setup_preset(spec, &alc883_presets[board_config]);
8053 spec->stream_name_analog = "ALC883 Analog";
8054 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8055 spec->stream_analog_capture = &alc883_pcm_analog_capture;
8056 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8058 spec->stream_name_digital = "ALC883 Digital";
8059 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8060 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8062 if (!spec->adc_nids && spec->input_mux) {
8063 spec->adc_nids = alc883_adc_nids;
8064 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8067 spec->vmaster_nid = 0x0c;
8069 codec->patch_ops = alc_patch_ops;
8070 if (board_config == ALC883_AUTO)
8071 spec->init_hook = alc883_auto_init;
8072 #ifdef CONFIG_SND_HDA_POWER_SAVE
8073 if (!spec->loopback.amplist)
8074 spec->loopback.amplist = alc883_loopbacks;
8084 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8085 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
8087 #define alc262_dac_nids alc260_dac_nids
8088 #define alc262_adc_nids alc882_adc_nids
8089 #define alc262_adc_nids_alt alc882_adc_nids_alt
8091 #define alc262_modes alc260_modes
8092 #define alc262_capture_source alc882_capture_source
8094 static struct snd_kcontrol_new alc262_base_mixer[] = {
8095 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8096 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8097 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8098 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8099 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8100 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8101 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8102 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8103 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8104 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8105 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8106 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8107 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8108 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8109 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8110 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8111 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8112 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8116 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8117 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8118 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8119 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8120 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8121 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8122 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8123 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8124 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8125 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8126 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8127 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8128 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8129 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8130 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8131 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8132 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8136 /* update HP, line and mono-out pins according to the master switch */
8137 static void alc262_hp_master_update(struct hda_codec *codec)
8139 struct alc_spec *spec = codec->spec;
8140 int val = spec->master_sw;
8143 snd_hda_codec_write_cache(codec, 0x1b, 0,
8144 AC_VERB_SET_PIN_WIDGET_CONTROL,
8146 snd_hda_codec_write_cache(codec, 0x15, 0,
8147 AC_VERB_SET_PIN_WIDGET_CONTROL,
8149 /* mono (speaker) depending on the HP jack sense */
8150 val = val && !spec->jack_present;
8151 snd_hda_codec_write_cache(codec, 0x16, 0,
8152 AC_VERB_SET_PIN_WIDGET_CONTROL,
8156 static void alc262_hp_bpc_automute(struct hda_codec *codec)
8158 struct alc_spec *spec = codec->spec;
8159 unsigned int presence;
8160 presence = snd_hda_codec_read(codec, 0x1b, 0,
8161 AC_VERB_GET_PIN_SENSE, 0);
8162 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8163 alc262_hp_master_update(codec);
8166 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8168 if ((res >> 26) != ALC880_HP_EVENT)
8170 alc262_hp_bpc_automute(codec);
8173 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8175 struct alc_spec *spec = codec->spec;
8176 unsigned int presence;
8177 presence = snd_hda_codec_read(codec, 0x15, 0,
8178 AC_VERB_GET_PIN_SENSE, 0);
8179 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8180 alc262_hp_master_update(codec);
8183 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8186 if ((res >> 26) != ALC880_HP_EVENT)
8188 alc262_hp_wildwest_automute(codec);
8191 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8192 struct snd_ctl_elem_value *ucontrol)
8194 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8195 struct alc_spec *spec = codec->spec;
8196 *ucontrol->value.integer.value = spec->master_sw;
8200 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8201 struct snd_ctl_elem_value *ucontrol)
8203 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8204 struct alc_spec *spec = codec->spec;
8205 int val = !!*ucontrol->value.integer.value;
8207 if (val == spec->master_sw)
8209 spec->master_sw = val;
8210 alc262_hp_master_update(codec);
8214 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
8216 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8217 .name = "Master Playback Switch",
8218 .info = snd_ctl_boolean_mono_info,
8219 .get = alc262_hp_master_sw_get,
8220 .put = alc262_hp_master_sw_put,
8222 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8223 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8224 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8225 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8227 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8229 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8230 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8231 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8232 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8233 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8234 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8235 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8236 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8237 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8238 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8239 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8240 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8241 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8242 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8246 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
8248 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8249 .name = "Master Playback Switch",
8250 .info = snd_ctl_boolean_mono_info,
8251 .get = alc262_hp_master_sw_get,
8252 .put = alc262_hp_master_sw_put,
8254 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8255 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8256 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8257 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8258 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8260 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8262 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8263 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
8264 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
8265 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8266 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8267 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8268 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8269 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8270 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8274 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8275 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8276 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8277 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
8281 /* mute/unmute internal speaker according to the hp jack and mute state */
8282 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8284 struct alc_spec *spec = codec->spec;
8286 if (force || !spec->sense_updated) {
8287 unsigned int present;
8288 present = snd_hda_codec_read(codec, 0x15, 0,
8289 AC_VERB_GET_PIN_SENSE, 0);
8290 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
8291 spec->sense_updated = 1;
8293 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8294 spec->jack_present ? HDA_AMP_MUTE : 0);
8297 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
8300 if ((res >> 26) != ALC880_HP_EVENT)
8302 alc262_hp_t5735_automute(codec, 1);
8305 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
8307 alc262_hp_t5735_automute(codec, 1);
8310 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
8311 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8312 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8313 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8314 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8315 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8316 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8317 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8321 static struct hda_verb alc262_hp_t5735_verbs[] = {
8322 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8323 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8325 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8329 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
8330 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8331 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8332 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8333 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8334 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8335 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8339 static struct hda_verb alc262_hp_rp5700_verbs[] = {
8340 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8341 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8342 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8343 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8344 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8345 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8346 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8347 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8348 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8349 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8353 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
8360 /* bind hp and internal speaker mute (with plug check) */
8361 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
8362 struct snd_ctl_elem_value *ucontrol)
8364 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8365 long *valp = ucontrol->value.integer.value;
8368 /* change hp mute */
8369 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
8371 valp[0] ? 0 : HDA_AMP_MUTE);
8372 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
8374 valp[1] ? 0 : HDA_AMP_MUTE);
8376 /* change speaker according to HP jack state */
8377 struct alc_spec *spec = codec->spec;
8379 if (spec->jack_present)
8380 mute = HDA_AMP_MUTE;
8382 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
8384 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8385 HDA_AMP_MUTE, mute);
8390 static struct snd_kcontrol_new alc262_sony_mixer[] = {
8391 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8393 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8394 .name = "Master Playback Switch",
8395 .info = snd_hda_mixer_amp_switch_info,
8396 .get = snd_hda_mixer_amp_switch_get,
8397 .put = alc262_sony_master_sw_put,
8398 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
8400 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8401 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8402 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8403 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8407 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8408 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8409 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8410 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8411 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8412 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8413 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8414 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8418 #define alc262_capture_mixer alc882_capture_mixer
8419 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
8422 * generic initialization of ADC, input mixers and output mixers
8424 static struct hda_verb alc262_init_verbs[] = {
8426 * Unmute ADC0-2 and set the default input to mic-in
8428 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8429 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8430 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8431 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8432 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8433 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8435 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8437 * Note: PASD motherboards uses the Line In 2 as the input for
8438 * front panel mic (mic 2)
8440 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8441 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8442 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8443 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8444 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8445 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8448 * Set up output mixers (0x0c - 0x0e)
8450 /* set vol=0 to output mixers */
8451 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8452 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8453 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8454 /* set up input amps for analog loopback */
8455 /* Amp Indices: DAC = 0, mixer = 1 */
8456 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8458 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8460 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8461 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8463 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8464 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8465 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8466 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8467 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8468 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8470 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8471 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8472 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8473 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8474 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8476 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8477 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8479 /* FIXME: use matrix-type input source selection */
8480 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8481 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8482 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8483 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8484 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8485 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8487 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8488 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8489 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8490 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8492 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8493 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8494 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8495 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8500 static struct hda_verb alc262_hippo_unsol_verbs[] = {
8501 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8502 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8506 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8507 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8508 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8509 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8511 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8512 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8516 static struct hda_verb alc262_sony_unsol_verbs[] = {
8517 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8518 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8519 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
8521 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8522 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8525 /* mute/unmute internal speaker according to the hp jack and mute state */
8526 static void alc262_hippo_automute(struct hda_codec *codec)
8528 struct alc_spec *spec = codec->spec;
8530 unsigned int present;
8532 /* need to execute and sync at first */
8533 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8534 present = snd_hda_codec_read(codec, 0x15, 0,
8535 AC_VERB_GET_PIN_SENSE, 0);
8536 spec->jack_present = (present & 0x80000000) != 0;
8537 if (spec->jack_present) {
8538 /* mute internal speaker */
8539 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8540 HDA_AMP_MUTE, HDA_AMP_MUTE);
8542 /* unmute internal speaker if necessary */
8543 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8544 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8545 HDA_AMP_MUTE, mute);
8549 /* unsolicited event for HP jack sensing */
8550 static void alc262_hippo_unsol_event(struct hda_codec *codec,
8553 if ((res >> 26) != ALC880_HP_EVENT)
8555 alc262_hippo_automute(codec);
8558 static void alc262_hippo1_automute(struct hda_codec *codec)
8561 unsigned int present;
8563 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8564 present = snd_hda_codec_read(codec, 0x1b, 0,
8565 AC_VERB_GET_PIN_SENSE, 0);
8566 present = (present & 0x80000000) != 0;
8568 /* mute internal speaker */
8569 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8570 HDA_AMP_MUTE, HDA_AMP_MUTE);
8572 /* unmute internal speaker if necessary */
8573 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8574 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8575 HDA_AMP_MUTE, mute);
8579 /* unsolicited event for HP jack sensing */
8580 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8583 if ((res >> 26) != ALC880_HP_EVENT)
8585 alc262_hippo1_automute(codec);
8590 * 0x14 = headphone/spdif-out, 0x15 = internal speaker
8593 #define ALC_HP_EVENT 0x37
8595 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8596 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8597 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8601 static struct hda_input_mux alc262_fujitsu_capture_source = {
8610 static struct hda_input_mux alc262_HP_capture_source = {
8614 { "Front Mic", 0x1 },
8621 static struct hda_input_mux alc262_HP_D7000_capture_source = {
8625 { "Front Mic", 0x2 },
8631 /* mute/unmute internal speaker according to the hp jack and mute state */
8632 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8634 struct alc_spec *spec = codec->spec;
8637 if (force || !spec->sense_updated) {
8638 unsigned int present;
8639 /* need to execute and sync at first */
8640 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8641 present = snd_hda_codec_read(codec, 0x14, 0,
8642 AC_VERB_GET_PIN_SENSE, 0);
8643 spec->jack_present = (present & 0x80000000) != 0;
8644 spec->sense_updated = 1;
8646 if (spec->jack_present) {
8647 /* mute internal speaker */
8648 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8649 HDA_AMP_MUTE, HDA_AMP_MUTE);
8651 /* unmute internal speaker if necessary */
8652 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8653 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8654 HDA_AMP_MUTE, mute);
8658 /* unsolicited event for HP jack sensing */
8659 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8662 if ((res >> 26) != ALC_HP_EVENT)
8664 alc262_fujitsu_automute(codec, 1);
8667 /* bind volumes of both NID 0x0c and 0x0d */
8668 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8669 .ops = &snd_hda_bind_vol,
8671 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8672 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8677 /* bind hp and internal speaker mute (with plug check) */
8678 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8679 struct snd_ctl_elem_value *ucontrol)
8681 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8682 long *valp = ucontrol->value.integer.value;
8685 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
8687 valp[0] ? 0 : HDA_AMP_MUTE);
8688 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
8690 valp[1] ? 0 : HDA_AMP_MUTE);
8692 alc262_fujitsu_automute(codec, 0);
8696 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
8697 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
8699 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8700 .name = "Master Playback Switch",
8701 .info = snd_hda_mixer_amp_switch_info,
8702 .get = snd_hda_mixer_amp_switch_get,
8703 .put = alc262_fujitsu_master_sw_put,
8704 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8706 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8707 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8708 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8709 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8710 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8711 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8712 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8713 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8717 /* additional init verbs for Benq laptops */
8718 static struct hda_verb alc262_EAPD_verbs[] = {
8719 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8720 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8724 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8725 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8726 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8728 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8729 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8733 /* Samsung Q1 Ultra Vista model setup */
8734 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8735 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8736 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8737 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8738 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8739 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8740 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8744 static struct hda_verb alc262_ultra_verbs[] = {
8745 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8746 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8747 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8748 /* Mic is on Node 0x19 */
8749 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8750 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
8751 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8752 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
8753 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8754 {0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
8755 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8759 static struct hda_input_mux alc262_ultra_capture_source = {
8766 /* mute/unmute internal speaker according to the hp jack and mute state */
8767 static void alc262_ultra_automute(struct hda_codec *codec)
8769 struct alc_spec *spec = codec->spec;
8771 unsigned int present;
8773 /* need to execute and sync at first */
8774 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8775 present = snd_hda_codec_read(codec, 0x15, 0,
8776 AC_VERB_GET_PIN_SENSE, 0);
8777 spec->jack_present = (present & 0x80000000) != 0;
8778 if (spec->jack_present) {
8779 /* mute internal speaker */
8780 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8781 HDA_AMP_MUTE, HDA_AMP_MUTE);
8783 /* unmute internal speaker if necessary */
8784 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8785 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8786 HDA_AMP_MUTE, mute);
8790 /* unsolicited event for HP jack sensing */
8791 static void alc262_ultra_unsol_event(struct hda_codec *codec,
8794 if ((res >> 26) != ALC880_HP_EVENT)
8796 alc262_ultra_automute(codec);
8799 /* add playback controls from the parsed DAC table */
8800 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8801 const struct auto_pin_cfg *cfg)
8806 spec->multiout.num_dacs = 1; /* only use one dac */
8807 spec->multiout.dac_nids = spec->private_dac_nids;
8808 spec->multiout.dac_nids[0] = 2;
8810 nid = cfg->line_out_pins[0];
8812 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8813 "Front Playback Volume",
8814 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8817 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8818 "Front Playback Switch",
8819 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8824 nid = cfg->speaker_pins[0];
8827 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8828 "Speaker Playback Volume",
8829 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8833 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8834 "Speaker Playback Switch",
8835 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8840 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8841 "Speaker Playback Switch",
8842 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8848 nid = cfg->hp_pins[0];
8850 /* spec->multiout.hp_nid = 2; */
8852 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8853 "Headphone Playback Volume",
8854 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8858 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8859 "Headphone Playback Switch",
8860 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8865 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8866 "Headphone Playback Switch",
8867 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8876 /* identical with ALC880 */
8877 #define alc262_auto_create_analog_input_ctls \
8878 alc880_auto_create_analog_input_ctls
8881 * generic initialization of ADC, input mixers and output mixers
8883 static struct hda_verb alc262_volume_init_verbs[] = {
8885 * Unmute ADC0-2 and set the default input to mic-in
8887 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8888 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8889 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8890 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8891 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8892 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8894 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8896 * Note: PASD motherboards uses the Line In 2 as the input for
8897 * front panel mic (mic 2)
8899 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8900 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8901 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8902 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8903 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8904 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8907 * Set up output mixers (0x0c - 0x0f)
8909 /* set vol=0 to output mixers */
8910 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8911 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8912 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8914 /* set up input amps for analog loopback */
8915 /* Amp Indices: DAC = 0, mixer = 1 */
8916 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8917 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8918 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8919 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8920 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8921 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8923 /* FIXME: use matrix-type input source selection */
8924 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8925 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8926 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8927 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8928 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8929 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8931 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8932 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8933 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8934 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8936 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8937 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8938 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8939 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8944 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8946 * Unmute ADC0-2 and set the default input to mic-in
8948 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8949 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8950 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8951 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8952 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8953 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8955 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8957 * Note: PASD motherboards uses the Line In 2 as the input for
8958 * front panel mic (mic 2)
8960 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8961 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8962 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8963 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8964 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8965 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8966 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8967 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8970 * Set up output mixers (0x0c - 0x0e)
8972 /* set vol=0 to output mixers */
8973 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8974 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8975 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8977 /* set up input amps for analog loopback */
8978 /* Amp Indices: DAC = 0, mixer = 1 */
8979 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8980 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8981 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8982 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8983 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8984 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8986 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8987 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8988 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8990 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8991 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8993 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8994 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8996 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8997 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8998 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8999 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9000 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9002 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9003 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9004 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9005 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9006 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9007 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9010 /* FIXME: use matrix-type input source selection */
9011 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9012 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9013 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9014 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9015 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9016 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9018 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9020 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9021 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9023 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9024 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9025 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9026 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9028 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9033 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
9035 * Unmute ADC0-2 and set the default input to mic-in
9037 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9038 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9039 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9040 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9041 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9042 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9044 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9046 * Note: PASD motherboards uses the Line In 2 as the input for front
9049 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9050 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9051 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9052 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9053 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9054 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9055 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9056 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9057 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9059 * Set up output mixers (0x0c - 0x0e)
9061 /* set vol=0 to output mixers */
9062 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9063 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9064 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9066 /* set up input amps for analog loopback */
9067 /* Amp Indices: DAC = 0, mixer = 1 */
9068 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9069 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9070 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9071 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9072 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9073 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9076 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
9077 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
9078 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
9079 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
9080 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
9081 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
9082 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
9084 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9085 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9087 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9088 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9090 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
9091 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9092 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9093 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9094 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9095 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9097 /* FIXME: use matrix-type input source selection */
9098 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9099 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9100 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
9101 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
9102 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
9103 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
9104 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
9105 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9106 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
9108 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9109 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9110 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9111 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9112 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9113 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9114 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9116 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9117 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9118 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9119 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9120 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9121 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9122 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9124 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9129 #ifdef CONFIG_SND_HDA_POWER_SAVE
9130 #define alc262_loopbacks alc880_loopbacks
9133 /* pcm configuration: identiacal with ALC880 */
9134 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
9135 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
9136 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
9137 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
9140 * BIOS auto configuration
9142 static int alc262_parse_auto_config(struct hda_codec *codec)
9144 struct alc_spec *spec = codec->spec;
9146 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
9148 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9152 if (!spec->autocfg.line_outs)
9153 return 0; /* can't find valid BIOS pin config */
9154 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
9157 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
9161 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9163 if (spec->autocfg.dig_out_pin)
9164 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
9165 if (spec->autocfg.dig_in_pin)
9166 spec->dig_in_nid = ALC262_DIGIN_NID;
9168 if (spec->kctl_alloc)
9169 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9171 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
9172 spec->num_mux_defs = 1;
9173 spec->input_mux = &spec->private_imux;
9175 err = alc_auto_add_mic_boost(codec);
9182 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
9183 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
9184 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
9187 /* init callback for auto-configuration model -- overriding the default init */
9188 static void alc262_auto_init(struct hda_codec *codec)
9190 alc262_auto_init_multi_out(codec);
9191 alc262_auto_init_hp_out(codec);
9192 alc262_auto_init_analog_input(codec);
9196 * configuration and preset
9198 static const char *alc262_models[ALC262_MODEL_LAST] = {
9199 [ALC262_BASIC] = "basic",
9200 [ALC262_HIPPO] = "hippo",
9201 [ALC262_HIPPO_1] = "hippo_1",
9202 [ALC262_FUJITSU] = "fujitsu",
9203 [ALC262_HP_BPC] = "hp-bpc",
9204 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
9205 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
9206 [ALC262_HP_RP5700] = "hp-rp5700",
9207 [ALC262_BENQ_ED8] = "benq",
9208 [ALC262_BENQ_T31] = "benq-t31",
9209 [ALC262_SONY_ASSAMD] = "sony-assamd",
9210 [ALC262_ULTRA] = "ultra",
9211 [ALC262_AUTO] = "auto",
9214 static struct snd_pci_quirk alc262_cfg_tbl[] = {
9215 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
9216 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
9217 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
9218 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
9219 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
9220 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
9221 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
9222 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
9223 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
9224 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
9225 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
9226 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
9227 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
9228 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
9229 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
9230 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
9231 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
9232 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
9233 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
9234 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
9235 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
9236 ALC262_HP_TC_T5735),
9237 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
9238 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9239 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
9240 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9241 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9242 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
9243 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
9244 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
9245 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
9246 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
9247 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
9248 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
9252 static struct alc_config_preset alc262_presets[] = {
9254 .mixers = { alc262_base_mixer },
9255 .init_verbs = { alc262_init_verbs },
9256 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9257 .dac_nids = alc262_dac_nids,
9259 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9260 .channel_mode = alc262_modes,
9261 .input_mux = &alc262_capture_source,
9264 .mixers = { alc262_base_mixer },
9265 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
9266 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9267 .dac_nids = alc262_dac_nids,
9269 .dig_out_nid = ALC262_DIGOUT_NID,
9270 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9271 .channel_mode = alc262_modes,
9272 .input_mux = &alc262_capture_source,
9273 .unsol_event = alc262_hippo_unsol_event,
9274 .init_hook = alc262_hippo_automute,
9276 [ALC262_HIPPO_1] = {
9277 .mixers = { alc262_hippo1_mixer },
9278 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
9279 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9280 .dac_nids = alc262_dac_nids,
9282 .dig_out_nid = ALC262_DIGOUT_NID,
9283 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9284 .channel_mode = alc262_modes,
9285 .input_mux = &alc262_capture_source,
9286 .unsol_event = alc262_hippo1_unsol_event,
9287 .init_hook = alc262_hippo1_automute,
9289 [ALC262_FUJITSU] = {
9290 .mixers = { alc262_fujitsu_mixer },
9291 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9292 alc262_fujitsu_unsol_verbs },
9293 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9294 .dac_nids = alc262_dac_nids,
9296 .dig_out_nid = ALC262_DIGOUT_NID,
9297 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9298 .channel_mode = alc262_modes,
9299 .input_mux = &alc262_fujitsu_capture_source,
9300 .unsol_event = alc262_fujitsu_unsol_event,
9303 .mixers = { alc262_HP_BPC_mixer },
9304 .init_verbs = { alc262_HP_BPC_init_verbs },
9305 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9306 .dac_nids = alc262_dac_nids,
9308 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9309 .channel_mode = alc262_modes,
9310 .input_mux = &alc262_HP_capture_source,
9311 .unsol_event = alc262_hp_bpc_unsol_event,
9312 .init_hook = alc262_hp_bpc_automute,
9314 [ALC262_HP_BPC_D7000_WF] = {
9315 .mixers = { alc262_HP_BPC_WildWest_mixer },
9316 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9317 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9318 .dac_nids = alc262_dac_nids,
9320 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9321 .channel_mode = alc262_modes,
9322 .input_mux = &alc262_HP_D7000_capture_source,
9323 .unsol_event = alc262_hp_wildwest_unsol_event,
9324 .init_hook = alc262_hp_wildwest_automute,
9326 [ALC262_HP_BPC_D7000_WL] = {
9327 .mixers = { alc262_HP_BPC_WildWest_mixer,
9328 alc262_HP_BPC_WildWest_option_mixer },
9329 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9330 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9331 .dac_nids = alc262_dac_nids,
9333 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9334 .channel_mode = alc262_modes,
9335 .input_mux = &alc262_HP_D7000_capture_source,
9336 .unsol_event = alc262_hp_wildwest_unsol_event,
9337 .init_hook = alc262_hp_wildwest_automute,
9339 [ALC262_HP_TC_T5735] = {
9340 .mixers = { alc262_hp_t5735_mixer },
9341 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
9342 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9343 .dac_nids = alc262_dac_nids,
9345 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9346 .channel_mode = alc262_modes,
9347 .input_mux = &alc262_capture_source,
9348 .unsol_event = alc262_hp_t5735_unsol_event,
9349 .init_hook = alc262_hp_t5735_init_hook,
9351 [ALC262_HP_RP5700] = {
9352 .mixers = { alc262_hp_rp5700_mixer },
9353 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
9354 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9355 .dac_nids = alc262_dac_nids,
9356 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9357 .channel_mode = alc262_modes,
9358 .input_mux = &alc262_hp_rp5700_capture_source,
9360 [ALC262_BENQ_ED8] = {
9361 .mixers = { alc262_base_mixer },
9362 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
9363 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9364 .dac_nids = alc262_dac_nids,
9366 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9367 .channel_mode = alc262_modes,
9368 .input_mux = &alc262_capture_source,
9370 [ALC262_SONY_ASSAMD] = {
9371 .mixers = { alc262_sony_mixer },
9372 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
9373 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9374 .dac_nids = alc262_dac_nids,
9376 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9377 .channel_mode = alc262_modes,
9378 .input_mux = &alc262_capture_source,
9379 .unsol_event = alc262_hippo_unsol_event,
9380 .init_hook = alc262_hippo_automute,
9382 [ALC262_BENQ_T31] = {
9383 .mixers = { alc262_benq_t31_mixer },
9384 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
9385 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9386 .dac_nids = alc262_dac_nids,
9388 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9389 .channel_mode = alc262_modes,
9390 .input_mux = &alc262_capture_source,
9391 .unsol_event = alc262_hippo_unsol_event,
9392 .init_hook = alc262_hippo_automute,
9395 .mixers = { alc262_ultra_mixer },
9396 .init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
9397 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9398 .dac_nids = alc262_dac_nids,
9400 .dig_out_nid = ALC262_DIGOUT_NID,
9401 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9402 .channel_mode = alc262_modes,
9403 .input_mux = &alc262_ultra_capture_source,
9404 .unsol_event = alc262_ultra_unsol_event,
9405 .init_hook = alc262_ultra_automute,
9409 static int patch_alc262(struct hda_codec *codec)
9411 struct alc_spec *spec;
9415 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9421 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
9426 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9427 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
9428 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9429 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
9433 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9437 if (board_config < 0) {
9438 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
9439 "trying auto-probe from BIOS...\n");
9440 board_config = ALC262_AUTO;
9443 if (board_config == ALC262_AUTO) {
9444 /* automatic parse from the BIOS config */
9445 err = alc262_parse_auto_config(codec);
9451 "hda_codec: Cannot set up configuration "
9452 "from BIOS. Using base mode...\n");
9453 board_config = ALC262_BASIC;
9457 if (board_config != ALC262_AUTO)
9458 setup_preset(spec, &alc262_presets[board_config]);
9460 spec->stream_name_analog = "ALC262 Analog";
9461 spec->stream_analog_playback = &alc262_pcm_analog_playback;
9462 spec->stream_analog_capture = &alc262_pcm_analog_capture;
9464 spec->stream_name_digital = "ALC262 Digital";
9465 spec->stream_digital_playback = &alc262_pcm_digital_playback;
9466 spec->stream_digital_capture = &alc262_pcm_digital_capture;
9468 if (!spec->adc_nids && spec->input_mux) {
9469 /* check whether NID 0x07 is valid */
9470 unsigned int wcap = get_wcaps(codec, 0x07);
9473 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9474 if (wcap != AC_WID_AUD_IN) {
9475 spec->adc_nids = alc262_adc_nids_alt;
9476 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
9477 spec->mixers[spec->num_mixers] =
9478 alc262_capture_alt_mixer;
9481 spec->adc_nids = alc262_adc_nids;
9482 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
9483 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
9488 spec->vmaster_nid = 0x0c;
9490 codec->patch_ops = alc_patch_ops;
9491 if (board_config == ALC262_AUTO)
9492 spec->init_hook = alc262_auto_init;
9493 #ifdef CONFIG_SND_HDA_POWER_SAVE
9494 if (!spec->loopback.amplist)
9495 spec->loopback.amplist = alc262_loopbacks;
9502 * ALC268 channel source setting (2 channel)
9504 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
9505 #define alc268_modes alc260_modes
9507 static hda_nid_t alc268_dac_nids[2] = {
9512 static hda_nid_t alc268_adc_nids[2] = {
9517 static hda_nid_t alc268_adc_nids_alt[1] = {
9522 static struct snd_kcontrol_new alc268_base_mixer[] = {
9523 /* output mixer control */
9524 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9525 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9526 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9527 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9528 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9529 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9530 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9534 static struct hda_verb alc268_eapd_verbs[] = {
9535 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9536 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9540 /* Toshiba specific */
9541 #define alc268_toshiba_automute alc262_hippo_automute
9543 static struct hda_verb alc268_toshiba_verbs[] = {
9544 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9549 /* bind volumes of both NID 0x02 and 0x03 */
9550 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
9551 .ops = &snd_hda_bind_vol,
9553 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
9554 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
9559 /* mute/unmute internal speaker according to the hp jack and mute state */
9560 static void alc268_acer_automute(struct hda_codec *codec, int force)
9562 struct alc_spec *spec = codec->spec;
9565 if (force || !spec->sense_updated) {
9566 unsigned int present;
9567 present = snd_hda_codec_read(codec, 0x14, 0,
9568 AC_VERB_GET_PIN_SENSE, 0);
9569 spec->jack_present = (present & 0x80000000) != 0;
9570 spec->sense_updated = 1;
9572 if (spec->jack_present)
9573 mute = HDA_AMP_MUTE; /* mute internal speaker */
9574 else /* unmute internal speaker if necessary */
9575 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9576 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9577 HDA_AMP_MUTE, mute);
9581 /* bind hp and internal speaker mute (with plug check) */
9582 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
9583 struct snd_ctl_elem_value *ucontrol)
9585 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9586 long *valp = ucontrol->value.integer.value;
9589 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9591 valp[0] ? 0 : HDA_AMP_MUTE);
9592 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9594 valp[1] ? 0 : HDA_AMP_MUTE);
9596 alc268_acer_automute(codec, 0);
9600 static struct snd_kcontrol_new alc268_acer_mixer[] = {
9601 /* output mixer control */
9602 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9604 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9605 .name = "Master Playback Switch",
9606 .info = snd_hda_mixer_amp_switch_info,
9607 .get = snd_hda_mixer_amp_switch_get,
9608 .put = alc268_acer_master_sw_put,
9609 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9611 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9612 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9613 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9617 static struct hda_verb alc268_acer_verbs[] = {
9618 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9619 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9621 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9625 /* unsolicited event for HP jack sensing */
9626 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9629 if ((res >> 26) != ALC880_HP_EVENT)
9631 alc268_toshiba_automute(codec);
9634 static void alc268_acer_unsol_event(struct hda_codec *codec,
9637 if ((res >> 26) != ALC880_HP_EVENT)
9639 alc268_acer_automute(codec, 1);
9642 static void alc268_acer_init_hook(struct hda_codec *codec)
9644 alc268_acer_automute(codec, 1);
9647 static struct snd_kcontrol_new alc268_dell_mixer[] = {
9648 /* output mixer control */
9649 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9650 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9651 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9652 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9653 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9654 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9658 static struct hda_verb alc268_dell_verbs[] = {
9659 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9661 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9665 /* mute/unmute internal speaker according to the hp jack and mute state */
9666 static void alc268_dell_automute(struct hda_codec *codec)
9668 unsigned int present;
9671 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
9672 if (present & 0x80000000)
9673 mute = HDA_AMP_MUTE;
9675 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9676 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9677 HDA_AMP_MUTE, mute);
9680 static void alc268_dell_unsol_event(struct hda_codec *codec,
9683 if ((res >> 26) != ALC880_HP_EVENT)
9685 alc268_dell_automute(codec);
9688 #define alc268_dell_init_hook alc268_dell_automute
9691 * generic initialization of ADC, input mixers and output mixers
9693 static struct hda_verb alc268_base_init_verbs[] = {
9694 /* Unmute DAC0-1 and set vol = 0 */
9695 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9696 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9697 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9698 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9699 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9700 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9703 * Set up output mixers (0x0c - 0x0e)
9705 /* set vol=0 to output mixers */
9706 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9707 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9708 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9709 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
9711 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9712 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9714 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9715 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9716 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9717 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9718 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9719 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9720 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9721 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9723 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9724 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9725 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9726 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9727 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9728 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9729 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9730 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9732 /* Unmute Selector 23h,24h and set the default input to mic-in */
9734 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
9735 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9736 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
9737 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9743 * generic initialization of ADC, input mixers and output mixers
9745 static struct hda_verb alc268_volume_init_verbs[] = {
9746 /* set output DAC */
9747 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9748 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9749 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9750 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9752 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9753 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9754 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9755 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9756 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9758 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9759 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9760 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9761 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9762 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9764 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9765 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9766 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9767 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9769 /* set PCBEEP vol = 0 */
9770 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
9775 #define alc268_mux_enum_info alc_mux_enum_info
9776 #define alc268_mux_enum_get alc_mux_enum_get
9778 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
9779 struct snd_ctl_elem_value *ucontrol)
9781 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9782 struct alc_spec *spec = codec->spec;
9784 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9785 static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
9786 hda_nid_t nid = capture_mixers[adc_idx];
9788 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
9790 &spec->cur_mux[adc_idx]);
9793 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9794 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9795 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9797 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9798 /* The multiple "Capture Source" controls confuse alsamixer
9799 * So call somewhat different..
9801 /* .name = "Capture Source", */
9802 .name = "Input Source",
9804 .info = alc268_mux_enum_info,
9805 .get = alc268_mux_enum_get,
9806 .put = alc268_mux_enum_put,
9811 static struct snd_kcontrol_new alc268_capture_mixer[] = {
9812 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9813 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9814 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9815 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9817 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9818 /* The multiple "Capture Source" controls confuse alsamixer
9819 * So call somewhat different..
9821 /* .name = "Capture Source", */
9822 .name = "Input Source",
9824 .info = alc268_mux_enum_info,
9825 .get = alc268_mux_enum_get,
9826 .put = alc268_mux_enum_put,
9831 static struct hda_input_mux alc268_capture_source = {
9835 { "Front Mic", 0x1 },
9841 #ifdef CONFIG_SND_DEBUG
9842 static struct snd_kcontrol_new alc268_test_mixer[] = {
9843 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9844 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9845 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9846 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9848 /* Volume widgets */
9849 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9850 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9851 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9852 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
9853 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
9854 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
9855 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
9856 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
9857 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
9858 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
9859 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
9860 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
9861 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
9862 /* The below appears problematic on some hardwares */
9863 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
9864 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9865 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
9866 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
9867 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
9869 /* Modes for retasking pin widgets */
9870 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
9871 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
9872 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
9873 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
9875 /* Controls for GPIO pins, assuming they are configured as outputs */
9876 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
9877 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
9878 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
9879 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
9881 /* Switches to allow the digital SPDIF output pin to be enabled.
9882 * The ALC268 does not have an SPDIF input.
9884 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
9886 /* A switch allowing EAPD to be enabled. Some laptops seem to use
9887 * this output to turn on an external amplifier.
9889 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
9890 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
9896 /* create input playback/capture controls for the given pin */
9897 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9898 const char *ctlname, int idx)
9903 sprintf(name, "%s Playback Volume", ctlname);
9905 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9906 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9910 } else if (nid == 0x15) {
9911 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9912 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9918 sprintf(name, "%s Playback Switch", ctlname);
9919 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9920 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9926 /* add playback controls from the parsed DAC table */
9927 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9928 const struct auto_pin_cfg *cfg)
9933 spec->multiout.num_dacs = 2; /* only use one dac */
9934 spec->multiout.dac_nids = spec->private_dac_nids;
9935 spec->multiout.dac_nids[0] = 2;
9936 spec->multiout.dac_nids[1] = 3;
9938 nid = cfg->line_out_pins[0];
9940 alc268_new_analog_output(spec, nid, "Front", 0);
9942 nid = cfg->speaker_pins[0];
9944 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9945 "Speaker Playback Volume",
9946 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9950 nid = cfg->hp_pins[0];
9952 alc268_new_analog_output(spec, nid, "Headphone", 0);
9954 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
9956 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9957 "Mono Playback Switch",
9958 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
9965 /* create playback/capture controls for input pins */
9966 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
9967 const struct auto_pin_cfg *cfg)
9969 struct hda_input_mux *imux = &spec->private_imux;
9972 for (i = 0; i < AUTO_PIN_LAST; i++) {
9973 switch(cfg->input_pins[i]) {
9975 idx1 = 0; /* Mic 1 */
9978 idx1 = 1; /* Mic 2 */
9981 idx1 = 2; /* Line In */
9989 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9990 imux->items[imux->num_items].index = idx1;
9996 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
9998 struct alc_spec *spec = codec->spec;
9999 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10000 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10001 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10002 unsigned int dac_vol1, dac_vol2;
10005 snd_hda_codec_write(codec, speaker_nid, 0,
10006 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
10007 snd_hda_codec_write(codec, 0x0f, 0,
10008 AC_VERB_SET_AMP_GAIN_MUTE,
10010 snd_hda_codec_write(codec, 0x10, 0,
10011 AC_VERB_SET_AMP_GAIN_MUTE,
10014 snd_hda_codec_write(codec, 0x0f, 0,
10015 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10016 snd_hda_codec_write(codec, 0x10, 0,
10017 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10020 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
10021 if (line_nid == 0x14)
10022 dac_vol2 = AMP_OUT_ZERO;
10023 else if (line_nid == 0x15)
10024 dac_vol1 = AMP_OUT_ZERO;
10025 if (hp_nid == 0x14)
10026 dac_vol2 = AMP_OUT_ZERO;
10027 else if (hp_nid == 0x15)
10028 dac_vol1 = AMP_OUT_ZERO;
10029 if (line_nid != 0x16 || hp_nid != 0x16 ||
10030 spec->autocfg.line_out_pins[1] != 0x16 ||
10031 spec->autocfg.line_out_pins[2] != 0x16)
10032 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
10034 snd_hda_codec_write(codec, 0x02, 0,
10035 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
10036 snd_hda_codec_write(codec, 0x03, 0,
10037 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
10040 /* pcm configuration: identiacal with ALC880 */
10041 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
10042 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
10043 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
10044 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
10047 * BIOS auto configuration
10049 static int alc268_parse_auto_config(struct hda_codec *codec)
10051 struct alc_spec *spec = codec->spec;
10053 static hda_nid_t alc268_ignore[] = { 0 };
10055 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10059 if (!spec->autocfg.line_outs)
10060 return 0; /* can't find valid BIOS pin config */
10062 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
10065 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
10069 spec->multiout.max_channels = 2;
10071 /* digital only support output */
10072 if (spec->autocfg.dig_out_pin)
10073 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
10075 if (spec->kctl_alloc)
10076 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10078 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
10079 spec->num_mux_defs = 1;
10080 spec->input_mux = &spec->private_imux;
10082 err = alc_auto_add_mic_boost(codec);
10089 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
10090 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
10091 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
10093 /* init callback for auto-configuration model -- overriding the default init */
10094 static void alc268_auto_init(struct hda_codec *codec)
10096 alc268_auto_init_multi_out(codec);
10097 alc268_auto_init_hp_out(codec);
10098 alc268_auto_init_mono_speaker_out(codec);
10099 alc268_auto_init_analog_input(codec);
10103 * configuration and preset
10105 static const char *alc268_models[ALC268_MODEL_LAST] = {
10106 [ALC268_3ST] = "3stack",
10107 [ALC268_TOSHIBA] = "toshiba",
10108 [ALC268_ACER] = "acer",
10109 [ALC268_DELL] = "dell",
10110 [ALC268_ZEPTO] = "zepto",
10111 #ifdef CONFIG_SND_DEBUG
10112 [ALC268_TEST] = "test",
10114 [ALC268_AUTO] = "auto",
10117 static struct snd_pci_quirk alc268_cfg_tbl[] = {
10118 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
10119 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
10120 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
10121 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
10122 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
10123 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
10124 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
10125 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
10126 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
10127 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
10128 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
10132 static struct alc_config_preset alc268_presets[] = {
10134 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
10135 .init_verbs = { alc268_base_init_verbs },
10136 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10137 .dac_nids = alc268_dac_nids,
10138 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10139 .adc_nids = alc268_adc_nids_alt,
10141 .dig_out_nid = ALC268_DIGOUT_NID,
10142 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10143 .channel_mode = alc268_modes,
10144 .input_mux = &alc268_capture_source,
10146 [ALC268_TOSHIBA] = {
10147 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
10148 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10149 alc268_toshiba_verbs },
10150 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10151 .dac_nids = alc268_dac_nids,
10152 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10153 .adc_nids = alc268_adc_nids_alt,
10155 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10156 .channel_mode = alc268_modes,
10157 .input_mux = &alc268_capture_source,
10158 .unsol_event = alc268_toshiba_unsol_event,
10159 .init_hook = alc268_toshiba_automute,
10162 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
10163 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10164 alc268_acer_verbs },
10165 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10166 .dac_nids = alc268_dac_nids,
10167 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10168 .adc_nids = alc268_adc_nids_alt,
10170 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10171 .channel_mode = alc268_modes,
10172 .input_mux = &alc268_capture_source,
10173 .unsol_event = alc268_acer_unsol_event,
10174 .init_hook = alc268_acer_init_hook,
10177 .mixers = { alc268_dell_mixer },
10178 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10179 alc268_dell_verbs },
10180 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10181 .dac_nids = alc268_dac_nids,
10183 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10184 .channel_mode = alc268_modes,
10185 .unsol_event = alc268_dell_unsol_event,
10186 .init_hook = alc268_dell_init_hook,
10187 .input_mux = &alc268_capture_source,
10190 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
10191 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10192 alc268_toshiba_verbs },
10193 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10194 .dac_nids = alc268_dac_nids,
10195 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10196 .adc_nids = alc268_adc_nids_alt,
10198 .dig_out_nid = ALC268_DIGOUT_NID,
10199 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10200 .channel_mode = alc268_modes,
10201 .input_mux = &alc268_capture_source,
10202 .unsol_event = alc268_toshiba_unsol_event,
10203 .init_hook = alc268_toshiba_automute
10205 #ifdef CONFIG_SND_DEBUG
10207 .mixers = { alc268_test_mixer, alc268_capture_mixer },
10208 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10209 alc268_volume_init_verbs },
10210 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10211 .dac_nids = alc268_dac_nids,
10212 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10213 .adc_nids = alc268_adc_nids_alt,
10215 .dig_out_nid = ALC268_DIGOUT_NID,
10216 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10217 .channel_mode = alc268_modes,
10218 .input_mux = &alc268_capture_source,
10223 static int patch_alc268(struct hda_codec *codec)
10225 struct alc_spec *spec;
10229 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
10233 codec->spec = spec;
10235 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
10239 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
10240 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
10241 "trying auto-probe from BIOS...\n");
10242 board_config = ALC268_AUTO;
10245 if (board_config == ALC268_AUTO) {
10246 /* automatic parse from the BIOS config */
10247 err = alc268_parse_auto_config(codec);
10253 "hda_codec: Cannot set up configuration "
10254 "from BIOS. Using base mode...\n");
10255 board_config = ALC268_3ST;
10259 if (board_config != ALC268_AUTO)
10260 setup_preset(spec, &alc268_presets[board_config]);
10262 spec->stream_name_analog = "ALC268 Analog";
10263 spec->stream_analog_playback = &alc268_pcm_analog_playback;
10264 spec->stream_analog_capture = &alc268_pcm_analog_capture;
10265 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
10267 spec->stream_name_digital = "ALC268 Digital";
10268 spec->stream_digital_playback = &alc268_pcm_digital_playback;
10270 if (!spec->adc_nids && spec->input_mux) {
10271 /* check whether NID 0x07 is valid */
10272 unsigned int wcap = get_wcaps(codec, 0x07);
10275 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10276 if (wcap != AC_WID_AUD_IN) {
10277 spec->adc_nids = alc268_adc_nids_alt;
10278 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
10279 spec->mixers[spec->num_mixers] =
10280 alc268_capture_alt_mixer;
10281 spec->num_mixers++;
10283 spec->adc_nids = alc268_adc_nids;
10284 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
10285 spec->mixers[spec->num_mixers] =
10286 alc268_capture_mixer;
10287 spec->num_mixers++;
10291 spec->vmaster_nid = 0x02;
10293 codec->patch_ops = alc_patch_ops;
10294 if (board_config == ALC268_AUTO)
10295 spec->init_hook = alc268_auto_init;
10301 * ALC269 channel source setting (2 channel)
10303 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
10305 #define alc269_dac_nids alc260_dac_nids
10307 static hda_nid_t alc269_adc_nids[1] = {
10312 #define alc269_modes alc260_modes
10313 #define alc269_capture_source alc880_lg_lw_capture_source
10315 static struct snd_kcontrol_new alc269_base_mixer[] = {
10316 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10317 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10318 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10319 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10320 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10321 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10322 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10323 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10324 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10325 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10326 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10327 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10331 /* capture mixer elements */
10332 static struct snd_kcontrol_new alc269_capture_mixer[] = {
10333 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10334 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10336 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10337 /* The multiple "Capture Source" controls confuse alsamixer
10338 * So call somewhat different..
10340 /* .name = "Capture Source", */
10341 .name = "Input Source",
10343 .info = alc_mux_enum_info,
10344 .get = alc_mux_enum_get,
10345 .put = alc_mux_enum_put,
10351 * generic initialization of ADC, input mixers and output mixers
10353 static struct hda_verb alc269_init_verbs[] = {
10355 * Unmute ADC0 and set the default input to mic-in
10357 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10359 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
10360 * analog-loopback mixer widget
10361 * Note: PASD motherboards uses the Line In 2 as the input for
10362 * front panel mic (mic 2)
10364 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10365 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10366 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10367 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10368 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10372 * Set up output mixers (0x0c - 0x0e)
10374 /* set vol=0 to output mixers */
10375 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10376 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10378 /* set up input amps for analog loopback */
10379 /* Amp Indices: DAC = 0, mixer = 1 */
10380 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10381 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10382 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10383 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10384 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10385 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10387 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10388 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10389 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10390 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10391 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10392 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10393 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10395 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10396 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10397 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10398 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10399 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10400 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10401 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10403 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10404 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10406 /* FIXME: use matrix-type input source selection */
10407 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
10408 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10409 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10410 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10411 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10412 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10415 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10416 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10420 /* add playback controls from the parsed DAC table */
10421 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
10422 const struct auto_pin_cfg *cfg)
10427 spec->multiout.num_dacs = 1; /* only use one dac */
10428 spec->multiout.dac_nids = spec->private_dac_nids;
10429 spec->multiout.dac_nids[0] = 2;
10431 nid = cfg->line_out_pins[0];
10433 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10434 "Front Playback Volume",
10435 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
10438 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10439 "Front Playback Switch",
10440 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10445 nid = cfg->speaker_pins[0];
10447 if (!cfg->line_out_pins[0]) {
10448 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10449 "Speaker Playback Volume",
10450 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10456 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10457 "Speaker Playback Switch",
10458 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10463 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10464 "Speaker Playback Switch",
10465 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10471 nid = cfg->hp_pins[0];
10473 /* spec->multiout.hp_nid = 2; */
10474 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
10475 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10476 "Headphone Playback Volume",
10477 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10483 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10484 "Headphone Playback Switch",
10485 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10490 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10491 "Headphone Playback Switch",
10492 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10501 #define alc269_auto_create_analog_input_ctls \
10502 alc880_auto_create_analog_input_ctls
10504 #ifdef CONFIG_SND_HDA_POWER_SAVE
10505 #define alc269_loopbacks alc880_loopbacks
10508 /* pcm configuration: identiacal with ALC880 */
10509 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
10510 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
10511 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
10512 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
10515 * BIOS auto configuration
10517 static int alc269_parse_auto_config(struct hda_codec *codec)
10519 struct alc_spec *spec = codec->spec;
10521 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
10523 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10528 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
10531 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
10535 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10537 if (spec->autocfg.dig_out_pin)
10538 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
10540 if (spec->kctl_alloc)
10541 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10543 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
10544 spec->num_mux_defs = 1;
10545 spec->input_mux = &spec->private_imux;
10547 err = alc_auto_add_mic_boost(codec);
10554 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
10555 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
10556 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
10559 /* init callback for auto-configuration model -- overriding the default init */
10560 static void alc269_auto_init(struct hda_codec *codec)
10562 alc269_auto_init_multi_out(codec);
10563 alc269_auto_init_hp_out(codec);
10564 alc269_auto_init_analog_input(codec);
10568 * configuration and preset
10570 static const char *alc269_models[ALC269_MODEL_LAST] = {
10571 [ALC269_BASIC] = "basic",
10574 static struct snd_pci_quirk alc269_cfg_tbl[] = {
10578 static struct alc_config_preset alc269_presets[] = {
10580 .mixers = { alc269_base_mixer },
10581 .init_verbs = { alc269_init_verbs },
10582 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
10583 .dac_nids = alc269_dac_nids,
10585 .num_channel_mode = ARRAY_SIZE(alc269_modes),
10586 .channel_mode = alc269_modes,
10587 .input_mux = &alc269_capture_source,
10591 static int patch_alc269(struct hda_codec *codec)
10593 struct alc_spec *spec;
10597 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10601 codec->spec = spec;
10603 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
10607 if (board_config < 0) {
10608 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
10609 "trying auto-probe from BIOS...\n");
10610 board_config = ALC269_AUTO;
10613 if (board_config == ALC269_AUTO) {
10614 /* automatic parse from the BIOS config */
10615 err = alc269_parse_auto_config(codec);
10621 "hda_codec: Cannot set up configuration "
10622 "from BIOS. Using base mode...\n");
10623 board_config = ALC269_BASIC;
10627 if (board_config != ALC269_AUTO)
10628 setup_preset(spec, &alc269_presets[board_config]);
10630 spec->stream_name_analog = "ALC269 Analog";
10631 spec->stream_analog_playback = &alc269_pcm_analog_playback;
10632 spec->stream_analog_capture = &alc269_pcm_analog_capture;
10634 spec->stream_name_digital = "ALC269 Digital";
10635 spec->stream_digital_playback = &alc269_pcm_digital_playback;
10636 spec->stream_digital_capture = &alc269_pcm_digital_capture;
10638 spec->adc_nids = alc269_adc_nids;
10639 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
10640 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
10641 spec->num_mixers++;
10643 codec->patch_ops = alc_patch_ops;
10644 if (board_config == ALC269_AUTO)
10645 spec->init_hook = alc269_auto_init;
10646 #ifdef CONFIG_SND_HDA_POWER_SAVE
10647 if (!spec->loopback.amplist)
10648 spec->loopback.amplist = alc269_loopbacks;
10655 * ALC861 channel source setting (2/6 channel selection for 3-stack)
10659 * set the path ways for 2 channel output
10660 * need to set the codec line out and mic 1 pin widgets to inputs
10662 static struct hda_verb alc861_threestack_ch2_init[] = {
10663 /* set pin widget 1Ah (line in) for input */
10664 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10665 /* set pin widget 18h (mic1/2) for input, for mic also enable
10668 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10670 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10672 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10673 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10679 * need to set the codec line out and mic 1 pin widgets to outputs
10681 static struct hda_verb alc861_threestack_ch6_init[] = {
10682 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10683 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10684 /* set pin widget 18h (mic1) for output (CLFE)*/
10685 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10687 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10688 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10690 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10692 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10693 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10698 static struct hda_channel_mode alc861_threestack_modes[2] = {
10699 { 2, alc861_threestack_ch2_init },
10700 { 6, alc861_threestack_ch6_init },
10702 /* Set mic1 as input and unmute the mixer */
10703 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
10704 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10705 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10708 /* Set mic1 as output and mute mixer */
10709 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
10710 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10711 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10715 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
10716 { 2, alc861_uniwill_m31_ch2_init },
10717 { 4, alc861_uniwill_m31_ch4_init },
10720 /* Set mic1 and line-in as input and unmute the mixer */
10721 static struct hda_verb alc861_asus_ch2_init[] = {
10722 /* set pin widget 1Ah (line in) for input */
10723 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10724 /* set pin widget 18h (mic1/2) for input, for mic also enable
10727 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10729 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10731 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10732 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10736 /* Set mic1 nad line-in as output and mute mixer */
10737 static struct hda_verb alc861_asus_ch6_init[] = {
10738 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10739 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10740 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10741 /* set pin widget 18h (mic1) for output (CLFE)*/
10742 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10743 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10744 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10745 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10747 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10749 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10750 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10755 static struct hda_channel_mode alc861_asus_modes[2] = {
10756 { 2, alc861_asus_ch2_init },
10757 { 6, alc861_asus_ch6_init },
10762 static struct snd_kcontrol_new alc861_base_mixer[] = {
10763 /* output mixer control */
10764 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10765 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10766 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10767 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10768 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10770 /*Input mixer control */
10771 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10772 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10773 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10774 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10775 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10776 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10777 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10778 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10779 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10780 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10782 /* Capture mixer control */
10783 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10784 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10786 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10787 .name = "Capture Source",
10789 .info = alc_mux_enum_info,
10790 .get = alc_mux_enum_get,
10791 .put = alc_mux_enum_put,
10796 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
10797 /* output mixer control */
10798 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10799 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10800 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10801 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10802 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10804 /* Input mixer control */
10805 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10806 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10807 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10808 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10809 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10810 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10811 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10812 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10813 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10814 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10816 /* Capture mixer control */
10817 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10818 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10820 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10821 .name = "Capture Source",
10823 .info = alc_mux_enum_info,
10824 .get = alc_mux_enum_get,
10825 .put = alc_mux_enum_put,
10828 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10829 .name = "Channel Mode",
10830 .info = alc_ch_mode_info,
10831 .get = alc_ch_mode_get,
10832 .put = alc_ch_mode_put,
10833 .private_value = ARRAY_SIZE(alc861_threestack_modes),
10838 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
10839 /* output mixer control */
10840 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10841 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10842 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10844 /*Capture mixer control */
10845 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10846 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10848 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10849 .name = "Capture Source",
10851 .info = alc_mux_enum_info,
10852 .get = alc_mux_enum_get,
10853 .put = alc_mux_enum_put,
10859 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
10860 /* output mixer control */
10861 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10862 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10863 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10864 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10865 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10867 /* Input mixer control */
10868 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10869 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10870 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10871 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10872 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10873 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10875 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10876 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10877 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10879 /* Capture mixer control */
10880 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10881 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10883 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10884 .name = "Capture Source",
10886 .info = alc_mux_enum_info,
10887 .get = alc_mux_enum_get,
10888 .put = alc_mux_enum_put,
10891 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10892 .name = "Channel Mode",
10893 .info = alc_ch_mode_info,
10894 .get = alc_ch_mode_get,
10895 .put = alc_ch_mode_put,
10896 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
10901 static struct snd_kcontrol_new alc861_asus_mixer[] = {
10902 /* output mixer control */
10903 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10904 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10905 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10906 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10907 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10909 /* Input mixer control */
10910 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10911 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10912 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10913 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10914 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10915 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10916 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10917 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10918 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10919 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
10921 /* Capture mixer control */
10922 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10923 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10925 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10926 .name = "Capture Source",
10928 .info = alc_mux_enum_info,
10929 .get = alc_mux_enum_get,
10930 .put = alc_mux_enum_put,
10933 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10934 .name = "Channel Mode",
10935 .info = alc_ch_mode_info,
10936 .get = alc_ch_mode_get,
10937 .put = alc_ch_mode_put,
10938 .private_value = ARRAY_SIZE(alc861_asus_modes),
10943 /* additional mixer */
10944 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
10945 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10946 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10947 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
10948 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
10953 * generic initialization of ADC, input mixers and output mixers
10955 static struct hda_verb alc861_base_init_verbs[] = {
10957 * Unmute ADC0 and set the default input to mic-in
10959 /* port-A for surround (rear panel) */
10960 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10961 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
10962 /* port-B for mic-in (rear panel) with vref */
10963 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10964 /* port-C for line-in (rear panel) */
10965 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10966 /* port-D for Front */
10967 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10968 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10969 /* port-E for HP out (front panel) */
10970 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10971 /* route front PCM to HP */
10972 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10973 /* port-F for mic-in (front panel) with vref */
10974 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10975 /* port-G for CLFE (rear panel) */
10976 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10977 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10978 /* port-H for side (rear panel) */
10979 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10980 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
10982 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10983 /* route front mic to ADC1*/
10984 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10985 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10987 /* Unmute DAC0~3 & spdif out*/
10988 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10989 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10990 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10991 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10992 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10994 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10995 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10996 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10997 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10998 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11000 /* Unmute Stereo Mixer 15 */
11001 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11002 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11003 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11004 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11006 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11007 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11008 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11009 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11010 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11011 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11012 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11013 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11014 /* hp used DAC 3 (Front) */
11015 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11016 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11021 static struct hda_verb alc861_threestack_init_verbs[] = {
11023 * Unmute ADC0 and set the default input to mic-in
11025 /* port-A for surround (rear panel) */
11026 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11027 /* port-B for mic-in (rear panel) with vref */
11028 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11029 /* port-C for line-in (rear panel) */
11030 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11031 /* port-D for Front */
11032 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11033 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11034 /* port-E for HP out (front panel) */
11035 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11036 /* route front PCM to HP */
11037 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11038 /* port-F for mic-in (front panel) with vref */
11039 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11040 /* port-G for CLFE (rear panel) */
11041 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11042 /* port-H for side (rear panel) */
11043 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11045 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11046 /* route front mic to ADC1*/
11047 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11048 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11049 /* Unmute DAC0~3 & spdif out*/
11050 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11051 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11052 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11053 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11054 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11056 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11057 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11058 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11059 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11060 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11062 /* Unmute Stereo Mixer 15 */
11063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11064 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11065 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11066 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11068 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11069 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11070 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11071 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11072 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11073 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11074 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11075 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11076 /* hp used DAC 3 (Front) */
11077 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11078 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11082 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
11084 * Unmute ADC0 and set the default input to mic-in
11086 /* port-A for surround (rear panel) */
11087 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11088 /* port-B for mic-in (rear panel) with vref */
11089 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11090 /* port-C for line-in (rear panel) */
11091 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11092 /* port-D for Front */
11093 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11094 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11095 /* port-E for HP out (front panel) */
11096 /* this has to be set to VREF80 */
11097 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11098 /* route front PCM to HP */
11099 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11100 /* port-F for mic-in (front panel) with vref */
11101 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11102 /* port-G for CLFE (rear panel) */
11103 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11104 /* port-H for side (rear panel) */
11105 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11107 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11108 /* route front mic to ADC1*/
11109 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11110 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11111 /* Unmute DAC0~3 & spdif out*/
11112 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11113 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11114 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11115 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11116 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11118 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11119 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11120 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11121 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11122 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11124 /* Unmute Stereo Mixer 15 */
11125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11126 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11127 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11128 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11130 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11131 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11132 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11133 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11134 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11135 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11136 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11137 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11138 /* hp used DAC 3 (Front) */
11139 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11140 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11144 static struct hda_verb alc861_asus_init_verbs[] = {
11146 * Unmute ADC0 and set the default input to mic-in
11148 /* port-A for surround (rear panel)
11149 * according to codec#0 this is the HP jack
11151 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
11152 /* route front PCM to HP */
11153 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
11154 /* port-B for mic-in (rear panel) with vref */
11155 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11156 /* port-C for line-in (rear panel) */
11157 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11158 /* port-D for Front */
11159 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11160 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11161 /* port-E for HP out (front panel) */
11162 /* this has to be set to VREF80 */
11163 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11164 /* route front PCM to HP */
11165 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11166 /* port-F for mic-in (front panel) with vref */
11167 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11168 /* port-G for CLFE (rear panel) */
11169 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11170 /* port-H for side (rear panel) */
11171 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11173 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11174 /* route front mic to ADC1*/
11175 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11176 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11177 /* Unmute DAC0~3 & spdif out*/
11178 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11179 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11180 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11181 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11182 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11183 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11184 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11185 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11186 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11187 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11189 /* Unmute Stereo Mixer 15 */
11190 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11191 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11192 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11193 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11195 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11196 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11197 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11198 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11199 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11200 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11201 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11202 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11203 /* hp used DAC 3 (Front) */
11204 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11205 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11209 /* additional init verbs for ASUS laptops */
11210 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
11211 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
11212 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
11217 * generic initialization of ADC, input mixers and output mixers
11219 static struct hda_verb alc861_auto_init_verbs[] = {
11221 * Unmute ADC0 and set the default input to mic-in
11223 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
11224 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11226 /* Unmute DAC0~3 & spdif out*/
11227 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11228 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11229 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11230 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11231 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11233 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11234 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11235 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11236 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11237 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11239 /* Unmute Stereo Mixer 15 */
11240 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11241 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11242 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11243 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
11245 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11246 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11247 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11248 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11249 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11250 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11251 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11252 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11254 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11255 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11256 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11257 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11258 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11259 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11260 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11261 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11263 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
11268 static struct hda_verb alc861_toshiba_init_verbs[] = {
11269 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11274 /* toggle speaker-output according to the hp-jack state */
11275 static void alc861_toshiba_automute(struct hda_codec *codec)
11277 unsigned int present;
11279 present = snd_hda_codec_read(codec, 0x0f, 0,
11280 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11281 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
11282 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11283 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
11284 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
11287 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
11290 if ((res >> 26) == ALC880_HP_EVENT)
11291 alc861_toshiba_automute(codec);
11294 /* pcm configuration: identiacal with ALC880 */
11295 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
11296 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
11297 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
11298 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
11301 #define ALC861_DIGOUT_NID 0x07
11303 static struct hda_channel_mode alc861_8ch_modes[1] = {
11307 static hda_nid_t alc861_dac_nids[4] = {
11308 /* front, surround, clfe, side */
11309 0x03, 0x06, 0x05, 0x04
11312 static hda_nid_t alc660_dac_nids[3] = {
11313 /* front, clfe, surround */
11317 static hda_nid_t alc861_adc_nids[1] = {
11322 static struct hda_input_mux alc861_capture_source = {
11326 { "Front Mic", 0x3 },
11333 /* fill in the dac_nids table from the parsed pin configuration */
11334 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
11335 const struct auto_pin_cfg *cfg)
11340 spec->multiout.dac_nids = spec->private_dac_nids;
11341 for (i = 0; i < cfg->line_outs; i++) {
11342 nid = cfg->line_out_pins[i];
11344 if (i >= ARRAY_SIZE(alc861_dac_nids))
11346 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
11349 spec->multiout.num_dacs = cfg->line_outs;
11353 /* add playback controls from the parsed DAC table */
11354 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
11355 const struct auto_pin_cfg *cfg)
11358 static const char *chname[4] = {
11359 "Front", "Surround", NULL /*CLFE*/, "Side"
11364 for (i = 0; i < cfg->line_outs; i++) {
11365 nid = spec->multiout.dac_nids[i];
11370 err = add_control(spec, ALC_CTL_BIND_MUTE,
11371 "Center Playback Switch",
11372 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11376 err = add_control(spec, ALC_CTL_BIND_MUTE,
11377 "LFE Playback Switch",
11378 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11383 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
11385 if (nid == alc861_dac_nids[idx])
11387 sprintf(name, "%s Playback Switch", chname[idx]);
11388 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11389 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11398 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
11406 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
11408 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11409 "Headphone Playback Switch",
11410 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11413 spec->multiout.hp_nid = nid;
11418 /* create playback/capture controls for input pins */
11419 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
11420 const struct auto_pin_cfg *cfg)
11422 struct hda_input_mux *imux = &spec->private_imux;
11423 int i, err, idx, idx1;
11425 for (i = 0; i < AUTO_PIN_LAST; i++) {
11426 switch (cfg->input_pins[i]) {
11429 idx = 2; /* Line In */
11433 idx = 2; /* Line In */
11437 idx = 1; /* Mic In */
11441 idx = 1; /* Mic In */
11451 err = new_analog_input(spec, cfg->input_pins[i],
11452 auto_pin_cfg_labels[i], idx, 0x15);
11456 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11457 imux->items[imux->num_items].index = idx1;
11463 static struct snd_kcontrol_new alc861_capture_mixer[] = {
11464 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11465 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11468 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11469 /* The multiple "Capture Source" controls confuse alsamixer
11470 * So call somewhat different..
11472 /* .name = "Capture Source", */
11473 .name = "Input Source",
11475 .info = alc_mux_enum_info,
11476 .get = alc_mux_enum_get,
11477 .put = alc_mux_enum_put,
11482 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
11484 int pin_type, int dac_idx)
11486 /* set as output */
11488 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11490 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11495 static void alc861_auto_init_multi_out(struct hda_codec *codec)
11497 struct alc_spec *spec = codec->spec;
11500 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
11501 for (i = 0; i < spec->autocfg.line_outs; i++) {
11502 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11503 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11505 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
11506 spec->multiout.dac_nids[i]);
11510 static void alc861_auto_init_hp_out(struct hda_codec *codec)
11512 struct alc_spec *spec = codec->spec;
11515 pin = spec->autocfg.hp_pins[0];
11516 if (pin) /* connect to front */
11517 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
11518 spec->multiout.dac_nids[0]);
11521 static void alc861_auto_init_analog_input(struct hda_codec *codec)
11523 struct alc_spec *spec = codec->spec;
11526 for (i = 0; i < AUTO_PIN_LAST; i++) {
11527 hda_nid_t nid = spec->autocfg.input_pins[i];
11528 if (nid >= 0x0c && nid <= 0x11) {
11529 snd_hda_codec_write(codec, nid, 0,
11530 AC_VERB_SET_PIN_WIDGET_CONTROL,
11531 i <= AUTO_PIN_FRONT_MIC ?
11532 PIN_VREF80 : PIN_IN);
11537 /* parse the BIOS configuration and set up the alc_spec */
11538 /* return 1 if successful, 0 if the proper config is not found,
11539 * or a negative error code
11541 static int alc861_parse_auto_config(struct hda_codec *codec)
11543 struct alc_spec *spec = codec->spec;
11545 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
11547 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11551 if (!spec->autocfg.line_outs)
11552 return 0; /* can't find valid BIOS pin config */
11554 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
11557 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
11560 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
11563 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
11567 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11569 if (spec->autocfg.dig_out_pin)
11570 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
11572 if (spec->kctl_alloc)
11573 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11575 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
11577 spec->num_mux_defs = 1;
11578 spec->input_mux = &spec->private_imux;
11580 spec->adc_nids = alc861_adc_nids;
11581 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
11582 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
11583 spec->num_mixers++;
11588 /* additional initialization for auto-configuration model */
11589 static void alc861_auto_init(struct hda_codec *codec)
11591 alc861_auto_init_multi_out(codec);
11592 alc861_auto_init_hp_out(codec);
11593 alc861_auto_init_analog_input(codec);
11596 #ifdef CONFIG_SND_HDA_POWER_SAVE
11597 static struct hda_amp_list alc861_loopbacks[] = {
11598 { 0x15, HDA_INPUT, 0 },
11599 { 0x15, HDA_INPUT, 1 },
11600 { 0x15, HDA_INPUT, 2 },
11601 { 0x15, HDA_INPUT, 3 },
11608 * configuration and preset
11610 static const char *alc861_models[ALC861_MODEL_LAST] = {
11611 [ALC861_3ST] = "3stack",
11612 [ALC660_3ST] = "3stack-660",
11613 [ALC861_3ST_DIG] = "3stack-dig",
11614 [ALC861_6ST_DIG] = "6stack-dig",
11615 [ALC861_UNIWILL_M31] = "uniwill-m31",
11616 [ALC861_TOSHIBA] = "toshiba",
11617 [ALC861_ASUS] = "asus",
11618 [ALC861_ASUS_LAPTOP] = "asus-laptop",
11619 [ALC861_AUTO] = "auto",
11622 static struct snd_pci_quirk alc861_cfg_tbl[] = {
11623 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
11624 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11625 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11626 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
11627 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
11628 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
11629 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
11630 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
11631 * Any other models that need this preset?
11633 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
11634 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
11635 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
11636 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
11637 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
11638 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
11639 /* FIXME: the below seems conflict */
11640 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
11641 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
11642 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
11646 static struct alc_config_preset alc861_presets[] = {
11648 .mixers = { alc861_3ST_mixer },
11649 .init_verbs = { alc861_threestack_init_verbs },
11650 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11651 .dac_nids = alc861_dac_nids,
11652 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11653 .channel_mode = alc861_threestack_modes,
11655 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11656 .adc_nids = alc861_adc_nids,
11657 .input_mux = &alc861_capture_source,
11659 [ALC861_3ST_DIG] = {
11660 .mixers = { alc861_base_mixer },
11661 .init_verbs = { alc861_threestack_init_verbs },
11662 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11663 .dac_nids = alc861_dac_nids,
11664 .dig_out_nid = ALC861_DIGOUT_NID,
11665 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11666 .channel_mode = alc861_threestack_modes,
11668 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11669 .adc_nids = alc861_adc_nids,
11670 .input_mux = &alc861_capture_source,
11672 [ALC861_6ST_DIG] = {
11673 .mixers = { alc861_base_mixer },
11674 .init_verbs = { alc861_base_init_verbs },
11675 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11676 .dac_nids = alc861_dac_nids,
11677 .dig_out_nid = ALC861_DIGOUT_NID,
11678 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
11679 .channel_mode = alc861_8ch_modes,
11680 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11681 .adc_nids = alc861_adc_nids,
11682 .input_mux = &alc861_capture_source,
11685 .mixers = { alc861_3ST_mixer },
11686 .init_verbs = { alc861_threestack_init_verbs },
11687 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
11688 .dac_nids = alc660_dac_nids,
11689 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11690 .channel_mode = alc861_threestack_modes,
11692 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11693 .adc_nids = alc861_adc_nids,
11694 .input_mux = &alc861_capture_source,
11696 [ALC861_UNIWILL_M31] = {
11697 .mixers = { alc861_uniwill_m31_mixer },
11698 .init_verbs = { alc861_uniwill_m31_init_verbs },
11699 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11700 .dac_nids = alc861_dac_nids,
11701 .dig_out_nid = ALC861_DIGOUT_NID,
11702 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
11703 .channel_mode = alc861_uniwill_m31_modes,
11705 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11706 .adc_nids = alc861_adc_nids,
11707 .input_mux = &alc861_capture_source,
11709 [ALC861_TOSHIBA] = {
11710 .mixers = { alc861_toshiba_mixer },
11711 .init_verbs = { alc861_base_init_verbs,
11712 alc861_toshiba_init_verbs },
11713 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11714 .dac_nids = alc861_dac_nids,
11715 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11716 .channel_mode = alc883_3ST_2ch_modes,
11717 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11718 .adc_nids = alc861_adc_nids,
11719 .input_mux = &alc861_capture_source,
11720 .unsol_event = alc861_toshiba_unsol_event,
11721 .init_hook = alc861_toshiba_automute,
11724 .mixers = { alc861_asus_mixer },
11725 .init_verbs = { alc861_asus_init_verbs },
11726 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11727 .dac_nids = alc861_dac_nids,
11728 .dig_out_nid = ALC861_DIGOUT_NID,
11729 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
11730 .channel_mode = alc861_asus_modes,
11733 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11734 .adc_nids = alc861_adc_nids,
11735 .input_mux = &alc861_capture_source,
11737 [ALC861_ASUS_LAPTOP] = {
11738 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
11739 .init_verbs = { alc861_asus_init_verbs,
11740 alc861_asus_laptop_init_verbs },
11741 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11742 .dac_nids = alc861_dac_nids,
11743 .dig_out_nid = ALC861_DIGOUT_NID,
11744 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11745 .channel_mode = alc883_3ST_2ch_modes,
11747 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11748 .adc_nids = alc861_adc_nids,
11749 .input_mux = &alc861_capture_source,
11754 static int patch_alc861(struct hda_codec *codec)
11756 struct alc_spec *spec;
11760 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11764 codec->spec = spec;
11766 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
11770 if (board_config < 0) {
11771 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
11772 "trying auto-probe from BIOS...\n");
11773 board_config = ALC861_AUTO;
11776 if (board_config == ALC861_AUTO) {
11777 /* automatic parse from the BIOS config */
11778 err = alc861_parse_auto_config(codec);
11784 "hda_codec: Cannot set up configuration "
11785 "from BIOS. Using base mode...\n");
11786 board_config = ALC861_3ST_DIG;
11790 if (board_config != ALC861_AUTO)
11791 setup_preset(spec, &alc861_presets[board_config]);
11793 spec->stream_name_analog = "ALC861 Analog";
11794 spec->stream_analog_playback = &alc861_pcm_analog_playback;
11795 spec->stream_analog_capture = &alc861_pcm_analog_capture;
11797 spec->stream_name_digital = "ALC861 Digital";
11798 spec->stream_digital_playback = &alc861_pcm_digital_playback;
11799 spec->stream_digital_capture = &alc861_pcm_digital_capture;
11801 spec->vmaster_nid = 0x03;
11803 codec->patch_ops = alc_patch_ops;
11804 if (board_config == ALC861_AUTO)
11805 spec->init_hook = alc861_auto_init;
11806 #ifdef CONFIG_SND_HDA_POWER_SAVE
11807 if (!spec->loopback.amplist)
11808 spec->loopback.amplist = alc861_loopbacks;
11815 * ALC861-VD support
11819 * In addition, an independent DAC
11821 #define ALC861VD_DIGOUT_NID 0x06
11823 static hda_nid_t alc861vd_dac_nids[4] = {
11824 /* front, surr, clfe, side surr */
11825 0x02, 0x03, 0x04, 0x05
11828 /* dac_nids for ALC660vd are in a different order - according to
11829 * Realtek's driver.
11830 * This should probably tesult in a different mixer for 6stack models
11831 * of ALC660vd codecs, but for now there is only 3stack mixer
11832 * - and it is the same as in 861vd.
11833 * adc_nids in ALC660vd are (is) the same as in 861vd
11835 static hda_nid_t alc660vd_dac_nids[3] = {
11836 /* front, rear, clfe, rear_surr */
11840 static hda_nid_t alc861vd_adc_nids[1] = {
11846 /* FIXME: should be a matrix-type input source selection */
11847 static struct hda_input_mux alc861vd_capture_source = {
11851 { "Front Mic", 0x1 },
11857 static struct hda_input_mux alc861vd_dallas_capture_source = {
11860 { "Front Mic", 0x0 },
11861 { "ATAPI Mic", 0x1 },
11862 { "Line In", 0x5 },
11866 static struct hda_input_mux alc861vd_hp_capture_source = {
11869 { "Front Mic", 0x0 },
11870 { "ATAPI Mic", 0x1 },
11874 #define alc861vd_mux_enum_info alc_mux_enum_info
11875 #define alc861vd_mux_enum_get alc_mux_enum_get
11877 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
11878 struct snd_ctl_elem_value *ucontrol)
11880 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11881 struct alc_spec *spec = codec->spec;
11882 const struct hda_input_mux *imux = spec->input_mux;
11883 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
11884 static hda_nid_t capture_mixers[1] = { 0x22 };
11885 hda_nid_t nid = capture_mixers[adc_idx];
11886 unsigned int *cur_val = &spec->cur_mux[adc_idx];
11887 unsigned int i, idx;
11889 idx = ucontrol->value.enumerated.item[0];
11890 if (idx >= imux->num_items)
11891 idx = imux->num_items - 1;
11892 if (*cur_val == idx)
11894 for (i = 0; i < imux->num_items; i++) {
11895 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
11896 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
11897 imux->items[i].index,
11907 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
11914 static struct hda_verb alc861vd_6stack_ch6_init[] = {
11915 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11916 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11917 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11918 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11925 static struct hda_verb alc861vd_6stack_ch8_init[] = {
11926 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11927 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11928 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11929 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11933 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
11934 { 6, alc861vd_6stack_ch6_init },
11935 { 8, alc861vd_6stack_ch8_init },
11938 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
11940 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11941 .name = "Channel Mode",
11942 .info = alc_ch_mode_info,
11943 .get = alc_ch_mode_get,
11944 .put = alc_ch_mode_put,
11949 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
11950 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11951 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11954 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11955 /* The multiple "Capture Source" controls confuse alsamixer
11956 * So call somewhat different..
11958 /* .name = "Capture Source", */
11959 .name = "Input Source",
11961 .info = alc861vd_mux_enum_info,
11962 .get = alc861vd_mux_enum_get,
11963 .put = alc861vd_mux_enum_put,
11968 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11969 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11971 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
11972 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11973 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11975 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11976 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
11978 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
11980 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
11982 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11983 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
11985 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
11986 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
11988 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11990 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11991 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11992 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11994 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11995 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11996 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12001 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12002 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12004 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12005 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12010 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
12011 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12012 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12014 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12016 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12017 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12018 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12020 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12021 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12022 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12024 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12025 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12027 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12028 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12030 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12031 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12036 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
12037 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12038 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
12039 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12041 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12043 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12044 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12045 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12047 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12048 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12049 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12051 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12052 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12057 /* Pin assignment: Front=0x14, HP = 0x15,
12058 * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
12060 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
12061 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12062 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12063 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12064 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12065 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12066 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12067 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12068 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12069 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
12070 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
12074 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
12075 * Front Mic=0x18, ATAPI Mic = 0x19,
12077 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
12078 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12079 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12080 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12081 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12082 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12083 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12084 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12085 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12091 * generic initialization of ADC, input mixers and output mixers
12093 static struct hda_verb alc861vd_volume_init_verbs[] = {
12095 * Unmute ADC0 and set the default input to mic-in
12097 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12098 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12100 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
12101 * the analog-loopback mixer widget
12103 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12105 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12106 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12107 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12108 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12110 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
12111 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12112 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12113 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12114 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12117 * Set up output mixers (0x02 - 0x05)
12119 /* set vol=0 to output mixers */
12120 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12121 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12122 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12123 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12125 /* set up input amps for analog loopback */
12126 /* Amp Indices: DAC = 0, mixer = 1 */
12127 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12128 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12129 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12130 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12131 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12132 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12133 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12134 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12140 * 3-stack pin configuration:
12141 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
12143 static struct hda_verb alc861vd_3stack_init_verbs[] = {
12145 * Set pin mode and muting
12147 /* set front pin widgets 0x14 for output */
12148 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12149 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12150 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12152 /* Mic (rear) pin: input vref at 80% */
12153 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12154 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12155 /* Front Mic pin: input vref at 80% */
12156 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12157 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12158 /* Line In pin: input */
12159 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12160 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12161 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12162 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12163 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12164 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12165 /* CD pin widget for input */
12166 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12172 * 6-stack pin configuration:
12174 static struct hda_verb alc861vd_6stack_init_verbs[] = {
12176 * Set pin mode and muting
12178 /* set front pin widgets 0x14 for output */
12179 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12180 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12181 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12183 /* Rear Pin: output 1 (0x0d) */
12184 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12185 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12186 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12187 /* CLFE Pin: output 2 (0x0e) */
12188 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12189 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12190 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
12191 /* Side Pin: output 3 (0x0f) */
12192 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12193 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12194 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
12196 /* Mic (rear) pin: input vref at 80% */
12197 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12198 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12199 /* Front Mic pin: input vref at 80% */
12200 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12201 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12202 /* Line In pin: input */
12203 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12204 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12205 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12206 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12207 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12208 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12209 /* CD pin widget for input */
12210 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12215 static struct hda_verb alc861vd_eapd_verbs[] = {
12216 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12220 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
12221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12222 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12223 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12224 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12225 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12229 /* toggle speaker-output according to the hp-jack state */
12230 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
12232 unsigned int present;
12233 unsigned char bits;
12235 present = snd_hda_codec_read(codec, 0x1b, 0,
12236 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12237 bits = present ? HDA_AMP_MUTE : 0;
12238 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12239 HDA_AMP_MUTE, bits);
12242 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
12244 unsigned int present;
12245 unsigned char bits;
12247 present = snd_hda_codec_read(codec, 0x18, 0,
12248 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12249 bits = present ? HDA_AMP_MUTE : 0;
12250 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
12251 HDA_AMP_MUTE, bits);
12254 static void alc861vd_lenovo_automute(struct hda_codec *codec)
12256 alc861vd_lenovo_hp_automute(codec);
12257 alc861vd_lenovo_mic_automute(codec);
12260 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
12263 switch (res >> 26) {
12264 case ALC880_HP_EVENT:
12265 alc861vd_lenovo_hp_automute(codec);
12267 case ALC880_MIC_EVENT:
12268 alc861vd_lenovo_mic_automute(codec);
12273 static struct hda_verb alc861vd_dallas_verbs[] = {
12274 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12275 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12276 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12277 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12279 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12280 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12281 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12282 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12283 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12284 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12285 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12286 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12288 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12289 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12291 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12292 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12293 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12294 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12295 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12297 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12298 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12299 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12300 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12301 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12302 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12303 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12304 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12306 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12307 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12308 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12309 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12311 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12312 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12313 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12318 /* toggle speaker-output according to the hp-jack state */
12319 static void alc861vd_dallas_automute(struct hda_codec *codec)
12321 unsigned int present;
12323 present = snd_hda_codec_read(codec, 0x15, 0,
12324 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12325 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12326 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
12329 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
12331 if ((res >> 26) == ALC880_HP_EVENT)
12332 alc861vd_dallas_automute(codec);
12335 #ifdef CONFIG_SND_HDA_POWER_SAVE
12336 #define alc861vd_loopbacks alc880_loopbacks
12339 /* pcm configuration: identiacal with ALC880 */
12340 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
12341 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
12342 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
12343 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
12346 * configuration and preset
12348 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
12349 [ALC660VD_3ST] = "3stack-660",
12350 [ALC660VD_3ST_DIG] = "3stack-660-digout",
12351 [ALC861VD_3ST] = "3stack",
12352 [ALC861VD_3ST_DIG] = "3stack-digout",
12353 [ALC861VD_6ST_DIG] = "6stack-digout",
12354 [ALC861VD_LENOVO] = "lenovo",
12355 [ALC861VD_DALLAS] = "dallas",
12356 [ALC861VD_HP] = "hp",
12357 [ALC861VD_AUTO] = "auto",
12360 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
12361 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
12362 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
12363 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
12364 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
12365 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
12366 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
12367 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
12368 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
12369 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
12370 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
12371 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
12372 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
12373 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
12374 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
12378 static struct alc_config_preset alc861vd_presets[] = {
12380 .mixers = { alc861vd_3st_mixer },
12381 .init_verbs = { alc861vd_volume_init_verbs,
12382 alc861vd_3stack_init_verbs },
12383 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12384 .dac_nids = alc660vd_dac_nids,
12385 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12386 .adc_nids = alc861vd_adc_nids,
12387 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12388 .channel_mode = alc861vd_3stack_2ch_modes,
12389 .input_mux = &alc861vd_capture_source,
12391 [ALC660VD_3ST_DIG] = {
12392 .mixers = { alc861vd_3st_mixer },
12393 .init_verbs = { alc861vd_volume_init_verbs,
12394 alc861vd_3stack_init_verbs },
12395 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12396 .dac_nids = alc660vd_dac_nids,
12397 .dig_out_nid = ALC861VD_DIGOUT_NID,
12398 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12399 .adc_nids = alc861vd_adc_nids,
12400 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12401 .channel_mode = alc861vd_3stack_2ch_modes,
12402 .input_mux = &alc861vd_capture_source,
12405 .mixers = { alc861vd_3st_mixer },
12406 .init_verbs = { alc861vd_volume_init_verbs,
12407 alc861vd_3stack_init_verbs },
12408 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12409 .dac_nids = alc861vd_dac_nids,
12410 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12411 .channel_mode = alc861vd_3stack_2ch_modes,
12412 .input_mux = &alc861vd_capture_source,
12414 [ALC861VD_3ST_DIG] = {
12415 .mixers = { alc861vd_3st_mixer },
12416 .init_verbs = { alc861vd_volume_init_verbs,
12417 alc861vd_3stack_init_verbs },
12418 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12419 .dac_nids = alc861vd_dac_nids,
12420 .dig_out_nid = ALC861VD_DIGOUT_NID,
12421 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12422 .channel_mode = alc861vd_3stack_2ch_modes,
12423 .input_mux = &alc861vd_capture_source,
12425 [ALC861VD_6ST_DIG] = {
12426 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
12427 .init_verbs = { alc861vd_volume_init_verbs,
12428 alc861vd_6stack_init_verbs },
12429 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12430 .dac_nids = alc861vd_dac_nids,
12431 .dig_out_nid = ALC861VD_DIGOUT_NID,
12432 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
12433 .channel_mode = alc861vd_6stack_modes,
12434 .input_mux = &alc861vd_capture_source,
12436 [ALC861VD_LENOVO] = {
12437 .mixers = { alc861vd_lenovo_mixer },
12438 .init_verbs = { alc861vd_volume_init_verbs,
12439 alc861vd_3stack_init_verbs,
12440 alc861vd_eapd_verbs,
12441 alc861vd_lenovo_unsol_verbs },
12442 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12443 .dac_nids = alc660vd_dac_nids,
12444 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12445 .adc_nids = alc861vd_adc_nids,
12446 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12447 .channel_mode = alc861vd_3stack_2ch_modes,
12448 .input_mux = &alc861vd_capture_source,
12449 .unsol_event = alc861vd_lenovo_unsol_event,
12450 .init_hook = alc861vd_lenovo_automute,
12452 [ALC861VD_DALLAS] = {
12453 .mixers = { alc861vd_dallas_mixer },
12454 .init_verbs = { alc861vd_dallas_verbs },
12455 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12456 .dac_nids = alc861vd_dac_nids,
12457 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12458 .adc_nids = alc861vd_adc_nids,
12459 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12460 .channel_mode = alc861vd_3stack_2ch_modes,
12461 .input_mux = &alc861vd_dallas_capture_source,
12462 .unsol_event = alc861vd_dallas_unsol_event,
12463 .init_hook = alc861vd_dallas_automute,
12466 .mixers = { alc861vd_hp_mixer },
12467 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
12468 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12469 .dac_nids = alc861vd_dac_nids,
12470 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12471 .dig_out_nid = ALC861VD_DIGOUT_NID,
12472 .adc_nids = alc861vd_adc_nids,
12473 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12474 .channel_mode = alc861vd_3stack_2ch_modes,
12475 .input_mux = &alc861vd_hp_capture_source,
12476 .unsol_event = alc861vd_dallas_unsol_event,
12477 .init_hook = alc861vd_dallas_automute,
12482 * BIOS auto configuration
12484 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
12485 hda_nid_t nid, int pin_type, int dac_idx)
12487 /* set as output */
12488 snd_hda_codec_write(codec, nid, 0,
12489 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
12490 snd_hda_codec_write(codec, nid, 0,
12491 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
12494 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
12496 struct alc_spec *spec = codec->spec;
12499 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
12500 for (i = 0; i <= HDA_SIDE; i++) {
12501 hda_nid_t nid = spec->autocfg.line_out_pins[i];
12502 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12504 alc861vd_auto_set_output_and_unmute(codec, nid,
12510 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
12512 struct alc_spec *spec = codec->spec;
12515 pin = spec->autocfg.hp_pins[0];
12516 if (pin) /* connect to front and use dac 0 */
12517 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
12520 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
12521 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
12523 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
12525 struct alc_spec *spec = codec->spec;
12528 for (i = 0; i < AUTO_PIN_LAST; i++) {
12529 hda_nid_t nid = spec->autocfg.input_pins[i];
12530 if (alc861vd_is_input_pin(nid)) {
12531 snd_hda_codec_write(codec, nid, 0,
12532 AC_VERB_SET_PIN_WIDGET_CONTROL,
12533 i <= AUTO_PIN_FRONT_MIC ?
12534 PIN_VREF80 : PIN_IN);
12535 if (nid != ALC861VD_PIN_CD_NID)
12536 snd_hda_codec_write(codec, nid, 0,
12537 AC_VERB_SET_AMP_GAIN_MUTE,
12543 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
12544 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
12546 /* add playback controls from the parsed DAC table */
12547 /* Based on ALC880 version. But ALC861VD has separate,
12548 * different NIDs for mute/unmute switch and volume control */
12549 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
12550 const struct auto_pin_cfg *cfg)
12553 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
12554 hda_nid_t nid_v, nid_s;
12557 for (i = 0; i < cfg->line_outs; i++) {
12558 if (!spec->multiout.dac_nids[i])
12560 nid_v = alc861vd_idx_to_mixer_vol(
12562 spec->multiout.dac_nids[i]));
12563 nid_s = alc861vd_idx_to_mixer_switch(
12565 spec->multiout.dac_nids[i]));
12569 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12570 "Center Playback Volume",
12571 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
12575 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12576 "LFE Playback Volume",
12577 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
12581 err = add_control(spec, ALC_CTL_BIND_MUTE,
12582 "Center Playback Switch",
12583 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
12587 err = add_control(spec, ALC_CTL_BIND_MUTE,
12588 "LFE Playback Switch",
12589 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
12594 sprintf(name, "%s Playback Volume", chname[i]);
12595 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12596 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
12600 sprintf(name, "%s Playback Switch", chname[i]);
12601 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12602 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
12611 /* add playback controls for speaker and HP outputs */
12612 /* Based on ALC880 version. But ALC861VD has separate,
12613 * different NIDs for mute/unmute switch and volume control */
12614 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
12615 hda_nid_t pin, const char *pfx)
12617 hda_nid_t nid_v, nid_s;
12624 if (alc880_is_fixed_pin(pin)) {
12625 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12626 /* specify the DAC as the extra output */
12627 if (!spec->multiout.hp_nid)
12628 spec->multiout.hp_nid = nid_v;
12630 spec->multiout.extra_out_nid[0] = nid_v;
12631 /* control HP volume/switch on the output mixer amp */
12632 nid_v = alc861vd_idx_to_mixer_vol(
12633 alc880_fixed_pin_idx(pin));
12634 nid_s = alc861vd_idx_to_mixer_switch(
12635 alc880_fixed_pin_idx(pin));
12637 sprintf(name, "%s Playback Volume", pfx);
12638 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12639 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
12642 sprintf(name, "%s Playback Switch", pfx);
12643 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12644 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
12647 } else if (alc880_is_multi_pin(pin)) {
12648 /* set manual connection */
12649 /* we have only a switch on HP-out PIN */
12650 sprintf(name, "%s Playback Switch", pfx);
12651 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12652 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12659 /* parse the BIOS configuration and set up the alc_spec
12660 * return 1 if successful, 0 if the proper config is not found,
12661 * or a negative error code
12662 * Based on ALC880 version - had to change it to override
12663 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
12664 static int alc861vd_parse_auto_config(struct hda_codec *codec)
12666 struct alc_spec *spec = codec->spec;
12668 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
12670 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12674 if (!spec->autocfg.line_outs)
12675 return 0; /* can't find valid BIOS pin config */
12677 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12680 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
12683 err = alc861vd_auto_create_extra_out(spec,
12684 spec->autocfg.speaker_pins[0],
12688 err = alc861vd_auto_create_extra_out(spec,
12689 spec->autocfg.hp_pins[0],
12693 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
12697 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12699 if (spec->autocfg.dig_out_pin)
12700 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
12702 if (spec->kctl_alloc)
12703 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12705 spec->init_verbs[spec->num_init_verbs++]
12706 = alc861vd_volume_init_verbs;
12708 spec->num_mux_defs = 1;
12709 spec->input_mux = &spec->private_imux;
12711 err = alc_auto_add_mic_boost(codec);
12718 /* additional initialization for auto-configuration model */
12719 static void alc861vd_auto_init(struct hda_codec *codec)
12721 alc861vd_auto_init_multi_out(codec);
12722 alc861vd_auto_init_hp_out(codec);
12723 alc861vd_auto_init_analog_input(codec);
12726 static int patch_alc861vd(struct hda_codec *codec)
12728 struct alc_spec *spec;
12729 int err, board_config;
12731 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12735 codec->spec = spec;
12737 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
12741 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
12742 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
12743 "ALC861VD, trying auto-probe from BIOS...\n");
12744 board_config = ALC861VD_AUTO;
12747 if (board_config == ALC861VD_AUTO) {
12748 /* automatic parse from the BIOS config */
12749 err = alc861vd_parse_auto_config(codec);
12755 "hda_codec: Cannot set up configuration "
12756 "from BIOS. Using base mode...\n");
12757 board_config = ALC861VD_3ST;
12761 if (board_config != ALC861VD_AUTO)
12762 setup_preset(spec, &alc861vd_presets[board_config]);
12764 spec->stream_name_analog = "ALC861VD Analog";
12765 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
12766 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
12768 spec->stream_name_digital = "ALC861VD Digital";
12769 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
12770 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
12772 spec->adc_nids = alc861vd_adc_nids;
12773 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
12775 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
12776 spec->num_mixers++;
12778 spec->vmaster_nid = 0x02;
12780 codec->patch_ops = alc_patch_ops;
12782 if (board_config == ALC861VD_AUTO)
12783 spec->init_hook = alc861vd_auto_init;
12784 #ifdef CONFIG_SND_HDA_POWER_SAVE
12785 if (!spec->loopback.amplist)
12786 spec->loopback.amplist = alc861vd_loopbacks;
12795 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
12796 * configuration. Each pin widget can choose any input DACs and a mixer.
12797 * Each ADC is connected from a mixer of all inputs. This makes possible
12798 * 6-channel independent captures.
12800 * In addition, an independent DAC for the multi-playback (not used in this
12803 #define ALC662_DIGOUT_NID 0x06
12804 #define ALC662_DIGIN_NID 0x0a
12806 static hda_nid_t alc662_dac_nids[4] = {
12807 /* front, rear, clfe, rear_surr */
12811 static hda_nid_t alc662_adc_nids[1] = {
12816 /* FIXME: should be a matrix-type input source selection */
12818 static struct hda_input_mux alc662_capture_source = {
12822 { "Front Mic", 0x1 },
12828 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
12836 static struct hda_input_mux alc662_eeepc_capture_source = {
12844 #define alc662_mux_enum_info alc_mux_enum_info
12845 #define alc662_mux_enum_get alc_mux_enum_get
12847 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
12848 struct snd_ctl_elem_value *ucontrol)
12850 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12851 struct alc_spec *spec = codec->spec;
12852 const struct hda_input_mux *imux = spec->input_mux;
12853 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
12854 static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
12855 hda_nid_t nid = capture_mixers[adc_idx];
12856 unsigned int *cur_val = &spec->cur_mux[adc_idx];
12857 unsigned int i, idx;
12859 idx = ucontrol->value.enumerated.item[0];
12860 if (idx >= imux->num_items)
12861 idx = imux->num_items - 1;
12862 if (*cur_val == idx)
12864 for (i = 0; i < imux->num_items; i++) {
12865 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
12866 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
12867 imux->items[i].index,
12876 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
12883 static struct hda_verb alc662_3ST_ch2_init[] = {
12884 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
12885 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12886 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
12887 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12894 static struct hda_verb alc662_3ST_ch6_init[] = {
12895 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12896 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12897 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
12898 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12899 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12900 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
12904 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
12905 { 2, alc662_3ST_ch2_init },
12906 { 6, alc662_3ST_ch6_init },
12912 static struct hda_verb alc662_sixstack_ch6_init[] = {
12913 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12914 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12915 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12922 static struct hda_verb alc662_sixstack_ch8_init[] = {
12923 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12924 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12925 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12929 static struct hda_channel_mode alc662_5stack_modes[2] = {
12930 { 2, alc662_sixstack_ch6_init },
12931 { 6, alc662_sixstack_ch8_init },
12934 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12935 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12938 static struct snd_kcontrol_new alc662_base_mixer[] = {
12939 /* output mixer control */
12940 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12941 HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
12942 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12943 HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12944 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12945 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12946 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12947 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12948 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12950 /*Input mixer control */
12951 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
12952 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
12953 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
12954 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
12955 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
12956 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
12957 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
12958 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
12962 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
12963 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12964 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12965 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12966 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12967 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12968 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12969 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12970 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12971 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12972 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12973 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12974 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12975 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12979 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
12980 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12981 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12982 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12983 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12984 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12985 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12986 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12987 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12988 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12989 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12990 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12991 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12992 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12993 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12994 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12995 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12996 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12997 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12998 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13002 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
13003 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13004 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
13005 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13006 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
13007 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13008 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13009 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13010 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13011 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13015 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
13016 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13018 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13019 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13021 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
13022 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13023 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13025 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
13026 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13027 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13031 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
13032 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13033 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13034 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13035 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
13036 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13037 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13038 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
13039 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
13040 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13041 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
13042 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13043 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13044 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13045 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13049 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
13051 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13052 .name = "Channel Mode",
13053 .info = alc_ch_mode_info,
13054 .get = alc_ch_mode_get,
13055 .put = alc_ch_mode_put,
13060 static struct hda_verb alc662_init_verbs[] = {
13061 /* ADC: mute amp left and right */
13062 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13063 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13064 /* Front mixer: unmute input/output amp left and right (volume = 0) */
13066 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13067 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13068 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13069 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13070 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13072 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13073 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13074 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13075 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13076 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13077 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13079 /* Front Pin: output 0 (0x0c) */
13080 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13081 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13083 /* Rear Pin: output 1 (0x0d) */
13084 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13085 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13087 /* CLFE Pin: output 2 (0x0e) */
13088 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13089 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13091 /* Mic (rear) pin: input vref at 80% */
13092 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13093 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13094 /* Front Mic pin: input vref at 80% */
13095 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13096 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13097 /* Line In pin: input */
13098 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13099 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13100 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13101 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13102 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13103 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13104 /* CD pin widget for input */
13105 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13107 /* FIXME: use matrix-type input source selection */
13108 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13110 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13111 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13112 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13113 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13115 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13116 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13117 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13118 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13122 static struct hda_verb alc662_sue_init_verbs[] = {
13123 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
13124 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
13128 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
13129 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13130 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13134 /* Set Unsolicited Event*/
13135 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
13136 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13137 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13142 * generic initialization of ADC, input mixers and output mixers
13144 static struct hda_verb alc662_auto_init_verbs[] = {
13146 * Unmute ADC and set the default input to mic-in
13148 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13149 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13151 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
13153 * Note: PASD motherboards uses the Line In 2 as the input for front
13154 * panel mic (mic 2)
13156 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13157 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13158 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13159 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13160 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13161 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13164 * Set up output mixers (0x0c - 0x0f)
13166 /* set vol=0 to output mixers */
13167 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13168 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13169 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13171 /* set up input amps for analog loopback */
13172 /* Amp Indices: DAC = 0, mixer = 1 */
13173 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13174 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13175 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13176 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13177 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13178 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13181 /* FIXME: use matrix-type input source selection */
13182 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13184 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13185 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13189 /* capture mixer elements */
13190 static struct snd_kcontrol_new alc662_capture_mixer[] = {
13191 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13192 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13194 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13195 /* The multiple "Capture Source" controls confuse alsamixer
13196 * So call somewhat different..
13198 /* .name = "Capture Source", */
13199 .name = "Input Source",
13201 .info = alc662_mux_enum_info,
13202 .get = alc662_mux_enum_get,
13203 .put = alc662_mux_enum_put,
13208 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
13210 unsigned int present;
13211 unsigned char bits;
13213 present = snd_hda_codec_read(codec, 0x14, 0,
13214 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13215 bits = present ? HDA_AMP_MUTE : 0;
13216 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13217 HDA_AMP_MUTE, bits);
13220 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
13222 unsigned int present;
13223 unsigned char bits;
13225 present = snd_hda_codec_read(codec, 0x1b, 0,
13226 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13227 bits = present ? HDA_AMP_MUTE : 0;
13228 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13229 HDA_AMP_MUTE, bits);
13230 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13231 HDA_AMP_MUTE, bits);
13234 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
13237 if ((res >> 26) == ALC880_HP_EVENT)
13238 alc662_lenovo_101e_all_automute(codec);
13239 if ((res >> 26) == ALC880_FRONT_EVENT)
13240 alc662_lenovo_101e_ispeaker_automute(codec);
13243 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
13245 unsigned int present;
13247 present = snd_hda_codec_read(codec, 0x18, 0,
13248 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13249 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13250 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13251 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13252 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13253 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13254 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13255 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13256 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13259 /* unsolicited event for HP jack sensing */
13260 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
13263 if ((res >> 26) == ALC880_HP_EVENT)
13264 alc262_hippo1_automute( codec );
13266 if ((res >> 26) == ALC880_MIC_EVENT)
13267 alc662_eeepc_mic_automute(codec);
13270 static void alc662_eeepc_inithook(struct hda_codec *codec)
13272 alc262_hippo1_automute( codec );
13273 alc662_eeepc_mic_automute(codec);
13276 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
13279 unsigned int present;
13281 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
13282 present = snd_hda_codec_read(codec, 0x14, 0,
13283 AC_VERB_GET_PIN_SENSE, 0);
13284 present = (present & 0x80000000) != 0;
13286 /* mute internal speaker */
13287 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13288 HDA_AMP_MUTE, HDA_AMP_MUTE);
13290 /* unmute internal speaker if necessary */
13291 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13292 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13293 HDA_AMP_MUTE, mute);
13297 /* unsolicited event for HP jack sensing */
13298 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
13301 if ((res >> 26) == ALC880_HP_EVENT)
13302 alc662_eeepc_ep20_automute(codec);
13305 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
13307 alc662_eeepc_ep20_automute(codec);
13310 #ifdef CONFIG_SND_HDA_POWER_SAVE
13311 #define alc662_loopbacks alc880_loopbacks
13315 /* pcm configuration: identiacal with ALC880 */
13316 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
13317 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
13318 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
13319 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
13322 * configuration and preset
13324 static const char *alc662_models[ALC662_MODEL_LAST] = {
13325 [ALC662_3ST_2ch_DIG] = "3stack-dig",
13326 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
13327 [ALC662_3ST_6ch] = "3stack-6ch",
13328 [ALC662_5ST_DIG] = "6stack-dig",
13329 [ALC662_LENOVO_101E] = "lenovo-101e",
13330 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
13331 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
13332 [ALC662_AUTO] = "auto",
13335 static struct snd_pci_quirk alc662_cfg_tbl[] = {
13336 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
13337 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
13338 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
13342 static struct alc_config_preset alc662_presets[] = {
13343 [ALC662_3ST_2ch_DIG] = {
13344 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
13345 .init_verbs = { alc662_init_verbs },
13346 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13347 .dac_nids = alc662_dac_nids,
13348 .dig_out_nid = ALC662_DIGOUT_NID,
13349 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13350 .adc_nids = alc662_adc_nids,
13351 .dig_in_nid = ALC662_DIGIN_NID,
13352 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13353 .channel_mode = alc662_3ST_2ch_modes,
13354 .input_mux = &alc662_capture_source,
13356 [ALC662_3ST_6ch_DIG] = {
13357 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13358 alc662_capture_mixer },
13359 .init_verbs = { alc662_init_verbs },
13360 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13361 .dac_nids = alc662_dac_nids,
13362 .dig_out_nid = ALC662_DIGOUT_NID,
13363 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13364 .adc_nids = alc662_adc_nids,
13365 .dig_in_nid = ALC662_DIGIN_NID,
13366 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13367 .channel_mode = alc662_3ST_6ch_modes,
13369 .input_mux = &alc662_capture_source,
13371 [ALC662_3ST_6ch] = {
13372 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13373 alc662_capture_mixer },
13374 .init_verbs = { alc662_init_verbs },
13375 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13376 .dac_nids = alc662_dac_nids,
13377 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13378 .adc_nids = alc662_adc_nids,
13379 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13380 .channel_mode = alc662_3ST_6ch_modes,
13382 .input_mux = &alc662_capture_source,
13384 [ALC662_5ST_DIG] = {
13385 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
13386 alc662_capture_mixer },
13387 .init_verbs = { alc662_init_verbs },
13388 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13389 .dac_nids = alc662_dac_nids,
13390 .dig_out_nid = ALC662_DIGOUT_NID,
13391 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13392 .adc_nids = alc662_adc_nids,
13393 .dig_in_nid = ALC662_DIGIN_NID,
13394 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
13395 .channel_mode = alc662_5stack_modes,
13396 .input_mux = &alc662_capture_source,
13398 [ALC662_LENOVO_101E] = {
13399 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
13400 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
13401 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13402 .dac_nids = alc662_dac_nids,
13403 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13404 .adc_nids = alc662_adc_nids,
13405 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13406 .channel_mode = alc662_3ST_2ch_modes,
13407 .input_mux = &alc662_lenovo_101e_capture_source,
13408 .unsol_event = alc662_lenovo_101e_unsol_event,
13409 .init_hook = alc662_lenovo_101e_all_automute,
13411 [ALC662_ASUS_EEEPC_P701] = {
13412 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
13413 .init_verbs = { alc662_init_verbs,
13414 alc662_eeepc_sue_init_verbs },
13415 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13416 .dac_nids = alc662_dac_nids,
13417 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
13418 .adc_nids = alc662_adc_nids,
13419 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13420 .channel_mode = alc662_3ST_2ch_modes,
13421 .input_mux = &alc662_eeepc_capture_source,
13422 .unsol_event = alc662_eeepc_unsol_event,
13423 .init_hook = alc662_eeepc_inithook,
13425 [ALC662_ASUS_EEEPC_EP20] = {
13426 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
13427 alc662_chmode_mixer },
13428 .init_verbs = { alc662_init_verbs,
13429 alc662_eeepc_ep20_sue_init_verbs },
13430 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13431 .dac_nids = alc662_dac_nids,
13432 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13433 .adc_nids = alc662_adc_nids,
13434 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13435 .channel_mode = alc662_3ST_6ch_modes,
13436 .input_mux = &alc662_lenovo_101e_capture_source,
13437 .unsol_event = alc662_eeepc_ep20_unsol_event,
13438 .init_hook = alc662_eeepc_ep20_inithook,
13445 * BIOS auto configuration
13448 /* add playback controls from the parsed DAC table */
13449 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
13450 const struct auto_pin_cfg *cfg)
13453 static const char *chname[4] = {
13454 "Front", "Surround", NULL /*CLFE*/, "Side"
13459 for (i = 0; i < cfg->line_outs; i++) {
13460 if (!spec->multiout.dac_nids[i])
13462 nid = alc880_idx_to_dac(i);
13465 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13466 "Center Playback Volume",
13467 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13471 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13472 "LFE Playback Volume",
13473 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13477 err = add_control(spec, ALC_CTL_BIND_MUTE,
13478 "Center Playback Switch",
13479 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
13483 err = add_control(spec, ALC_CTL_BIND_MUTE,
13484 "LFE Playback Switch",
13485 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
13490 sprintf(name, "%s Playback Volume", chname[i]);
13491 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13492 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13496 sprintf(name, "%s Playback Switch", chname[i]);
13497 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13498 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
13507 /* add playback controls for speaker and HP outputs */
13508 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
13518 if (alc880_is_fixed_pin(pin)) {
13519 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13520 /* printk("DAC nid=%x\n",nid); */
13521 /* specify the DAC as the extra output */
13522 if (!spec->multiout.hp_nid)
13523 spec->multiout.hp_nid = nid;
13525 spec->multiout.extra_out_nid[0] = nid;
13526 /* control HP volume/switch on the output mixer amp */
13527 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13528 sprintf(name, "%s Playback Volume", pfx);
13529 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13530 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13533 sprintf(name, "%s Playback Switch", pfx);
13534 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13535 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
13538 } else if (alc880_is_multi_pin(pin)) {
13539 /* set manual connection */
13540 /* we have only a switch on HP-out PIN */
13541 sprintf(name, "%s Playback Switch", pfx);
13542 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
13543 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
13550 /* create playback/capture controls for input pins */
13551 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
13552 const struct auto_pin_cfg *cfg)
13554 struct hda_input_mux *imux = &spec->private_imux;
13557 for (i = 0; i < AUTO_PIN_LAST; i++) {
13558 if (alc880_is_input_pin(cfg->input_pins[i])) {
13559 idx = alc880_input_pin_idx(cfg->input_pins[i]);
13560 err = new_analog_input(spec, cfg->input_pins[i],
13561 auto_pin_cfg_labels[i],
13565 imux->items[imux->num_items].label =
13566 auto_pin_cfg_labels[i];
13567 imux->items[imux->num_items].index =
13568 alc880_input_pin_idx(cfg->input_pins[i]);
13575 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
13576 hda_nid_t nid, int pin_type,
13579 /* set as output */
13580 snd_hda_codec_write(codec, nid, 0,
13581 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
13582 snd_hda_codec_write(codec, nid, 0,
13583 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
13584 /* need the manual connection? */
13585 if (alc880_is_multi_pin(nid)) {
13586 struct alc_spec *spec = codec->spec;
13587 int idx = alc880_multi_pin_idx(nid);
13588 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
13589 AC_VERB_SET_CONNECT_SEL,
13590 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
13594 static void alc662_auto_init_multi_out(struct hda_codec *codec)
13596 struct alc_spec *spec = codec->spec;
13599 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
13600 for (i = 0; i <= HDA_SIDE; i++) {
13601 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13602 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13604 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
13609 static void alc662_auto_init_hp_out(struct hda_codec *codec)
13611 struct alc_spec *spec = codec->spec;
13614 pin = spec->autocfg.hp_pins[0];
13615 if (pin) /* connect to front */
13617 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
13620 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
13621 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
13623 static void alc662_auto_init_analog_input(struct hda_codec *codec)
13625 struct alc_spec *spec = codec->spec;
13628 for (i = 0; i < AUTO_PIN_LAST; i++) {
13629 hda_nid_t nid = spec->autocfg.input_pins[i];
13630 if (alc662_is_input_pin(nid)) {
13631 snd_hda_codec_write(codec, nid, 0,
13632 AC_VERB_SET_PIN_WIDGET_CONTROL,
13633 (i <= AUTO_PIN_FRONT_MIC ?
13634 PIN_VREF80 : PIN_IN));
13635 if (nid != ALC662_PIN_CD_NID)
13636 snd_hda_codec_write(codec, nid, 0,
13637 AC_VERB_SET_AMP_GAIN_MUTE,
13643 static int alc662_parse_auto_config(struct hda_codec *codec)
13645 struct alc_spec *spec = codec->spec;
13647 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
13649 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13653 if (!spec->autocfg.line_outs)
13654 return 0; /* can't find valid BIOS pin config */
13656 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13659 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
13662 err = alc662_auto_create_extra_out(spec,
13663 spec->autocfg.speaker_pins[0],
13667 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
13671 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
13675 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13677 if (spec->autocfg.dig_out_pin)
13678 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
13680 if (spec->kctl_alloc)
13681 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13683 spec->num_mux_defs = 1;
13684 spec->input_mux = &spec->private_imux;
13686 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
13687 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
13688 spec->num_mixers++;
13692 /* additional initialization for auto-configuration model */
13693 static void alc662_auto_init(struct hda_codec *codec)
13695 alc662_auto_init_multi_out(codec);
13696 alc662_auto_init_hp_out(codec);
13697 alc662_auto_init_analog_input(codec);
13700 static int patch_alc662(struct hda_codec *codec)
13702 struct alc_spec *spec;
13703 int err, board_config;
13705 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13709 codec->spec = spec;
13711 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
13714 if (board_config < 0) {
13715 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
13716 "trying auto-probe from BIOS...\n");
13717 board_config = ALC662_AUTO;
13720 if (board_config == ALC662_AUTO) {
13721 /* automatic parse from the BIOS config */
13722 err = alc662_parse_auto_config(codec);
13728 "hda_codec: Cannot set up configuration "
13729 "from BIOS. Using base mode...\n");
13730 board_config = ALC662_3ST_2ch_DIG;
13734 if (board_config != ALC662_AUTO)
13735 setup_preset(spec, &alc662_presets[board_config]);
13737 spec->stream_name_analog = "ALC662 Analog";
13738 spec->stream_analog_playback = &alc662_pcm_analog_playback;
13739 spec->stream_analog_capture = &alc662_pcm_analog_capture;
13741 spec->stream_name_digital = "ALC662 Digital";
13742 spec->stream_digital_playback = &alc662_pcm_digital_playback;
13743 spec->stream_digital_capture = &alc662_pcm_digital_capture;
13745 if (!spec->adc_nids && spec->input_mux) {
13746 spec->adc_nids = alc662_adc_nids;
13747 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
13750 spec->vmaster_nid = 0x02;
13752 codec->patch_ops = alc_patch_ops;
13753 if (board_config == ALC662_AUTO)
13754 spec->init_hook = alc662_auto_init;
13755 #ifdef CONFIG_SND_HDA_POWER_SAVE
13756 if (!spec->loopback.amplist)
13757 spec->loopback.amplist = alc662_loopbacks;
13766 struct hda_codec_preset snd_hda_preset_realtek[] = {
13767 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
13768 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
13769 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
13770 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
13771 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
13772 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
13773 .patch = patch_alc861 },
13774 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
13775 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
13776 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
13777 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
13778 .patch = patch_alc883 },
13779 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
13780 .patch = patch_alc662 },
13781 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
13782 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
13783 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
13784 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
13785 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
13786 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
13787 {} /* terminator */