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 <sound/driver.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <sound/core.h>
32 #include "hda_codec.h"
33 #include "hda_local.h"
35 #define ALC880_FRONT_EVENT 0x01
36 #define ALC880_DCVOL_EVENT 0x02
37 #define ALC880_HP_EVENT 0x04
38 #define ALC880_MIC_EVENT 0x08
40 /* ALC880 board config type */
63 #ifdef CONFIG_SND_DEBUG
67 ALC880_MODEL_LAST /* last tag */
79 #ifdef CONFIG_SND_DEBUG
83 ALC260_MODEL_LAST /* last tag */
93 ALC262_HP_BPC_D7000_WL,
94 ALC262_HP_BPC_D7000_WF,
101 ALC262_MODEL_LAST /* last tag */
110 ALC268_MODEL_LAST /* last tag */
117 ALC269_MODEL_LAST /* last tag */
134 /* ALC861-VD models */
155 ALC662_ASUS_EEEPC_P701,
183 ALC883_TARGA_2ch_DIG,
189 ALC883_LENOVO_101E_2ch,
190 ALC883_LENOVO_NB0763,
191 ALC888_LENOVO_MS7195_DIG,
201 #define GPIO_MASK 0x03
204 /* codec parameterization */
205 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
206 unsigned int num_mixers;
208 const struct hda_verb *init_verbs[5]; /* initialization verbs
212 unsigned int num_init_verbs;
214 char *stream_name_analog; /* analog PCM stream */
215 struct hda_pcm_stream *stream_analog_playback;
216 struct hda_pcm_stream *stream_analog_capture;
218 char *stream_name_digital; /* digital PCM stream */
219 struct hda_pcm_stream *stream_digital_playback;
220 struct hda_pcm_stream *stream_digital_capture;
223 struct hda_multi_out multiout; /* playback set-up
224 * max_channels, dacs must be set
225 * dig_out_nid and hp_nid are optional
229 unsigned int num_adc_nids;
231 hda_nid_t dig_in_nid; /* digital-in NID; optional */
234 unsigned int num_mux_defs;
235 const struct hda_input_mux *input_mux;
236 unsigned int cur_mux[3];
239 const struct hda_channel_mode *channel_mode;
240 int num_channel_mode;
243 /* PCM information */
244 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
246 /* dynamic controls, init_verbs and input_mux */
247 struct auto_pin_cfg autocfg;
248 unsigned int num_kctl_alloc, num_kctl_used;
249 struct snd_kcontrol_new *kctl_alloc;
250 struct hda_input_mux private_imux;
251 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
254 void (*init_hook)(struct hda_codec *codec);
255 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
257 /* for pin sensing */
258 unsigned int sense_updated: 1;
259 unsigned int jack_present: 1;
261 #ifdef CONFIG_SND_HDA_POWER_SAVE
262 struct hda_loopback_check loopback;
267 * configuration template - to be copied to the spec instance
269 struct alc_config_preset {
270 struct snd_kcontrol_new *mixers[5]; /* should be identical size
273 const struct hda_verb *init_verbs[5];
274 unsigned int num_dacs;
276 hda_nid_t dig_out_nid; /* optional */
277 hda_nid_t hp_nid; /* optional */
278 unsigned int num_adc_nids;
280 hda_nid_t dig_in_nid;
281 unsigned int num_channel_mode;
282 const struct hda_channel_mode *channel_mode;
284 unsigned int num_mux_defs;
285 const struct hda_input_mux *input_mux;
286 void (*unsol_event)(struct hda_codec *, unsigned int);
287 void (*init_hook)(struct hda_codec *);
288 #ifdef CONFIG_SND_HDA_POWER_SAVE
289 struct hda_amp_list *loopbacks;
297 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
298 struct snd_ctl_elem_info *uinfo)
300 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
301 struct alc_spec *spec = codec->spec;
302 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
303 if (mux_idx >= spec->num_mux_defs)
305 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
308 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
309 struct snd_ctl_elem_value *ucontrol)
311 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
312 struct alc_spec *spec = codec->spec;
313 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
315 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
319 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
320 struct snd_ctl_elem_value *ucontrol)
322 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
323 struct alc_spec *spec = codec->spec;
324 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
325 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
326 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
327 spec->adc_nids[adc_idx],
328 &spec->cur_mux[adc_idx]);
333 * channel mode setting
335 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
336 struct snd_ctl_elem_info *uinfo)
338 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
339 struct alc_spec *spec = codec->spec;
340 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
341 spec->num_channel_mode);
344 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
345 struct snd_ctl_elem_value *ucontrol)
347 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
348 struct alc_spec *spec = codec->spec;
349 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
350 spec->num_channel_mode,
351 spec->multiout.max_channels);
354 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
357 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
358 struct alc_spec *spec = codec->spec;
359 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
360 spec->num_channel_mode,
361 &spec->multiout.max_channels);
362 if (err >= 0 && spec->need_dac_fix)
363 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
368 * Control the mode of pin widget settings via the mixer. "pc" is used
369 * instead of "%" to avoid consequences of accidently treating the % as
370 * being part of a format specifier. Maximum allowed length of a value is
371 * 63 characters plus NULL terminator.
373 * Note: some retasking pin complexes seem to ignore requests for input
374 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
375 * are requested. Therefore order this list so that this behaviour will not
376 * cause problems when mixer clients move through the enum sequentially.
377 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
380 static char *alc_pin_mode_names[] = {
381 "Mic 50pc bias", "Mic 80pc bias",
382 "Line in", "Line out", "Headphone out",
384 static unsigned char alc_pin_mode_values[] = {
385 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
387 /* The control can present all 5 options, or it can limit the options based
388 * in the pin being assumed to be exclusively an input or an output pin. In
389 * addition, "input" pins may or may not process the mic bias option
390 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
391 * accept requests for bias as of chip versions up to March 2006) and/or
392 * wiring in the computer.
394 #define ALC_PIN_DIR_IN 0x00
395 #define ALC_PIN_DIR_OUT 0x01
396 #define ALC_PIN_DIR_INOUT 0x02
397 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
398 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
400 /* Info about the pin modes supported by the different pin direction modes.
401 * For each direction the minimum and maximum values are given.
403 static signed char alc_pin_mode_dir_info[5][2] = {
404 { 0, 2 }, /* ALC_PIN_DIR_IN */
405 { 3, 4 }, /* ALC_PIN_DIR_OUT */
406 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
407 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
408 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
410 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
411 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
412 #define alc_pin_mode_n_items(_dir) \
413 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
415 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
416 struct snd_ctl_elem_info *uinfo)
418 unsigned int item_num = uinfo->value.enumerated.item;
419 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
421 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
423 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
425 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
426 item_num = alc_pin_mode_min(dir);
427 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
431 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
432 struct snd_ctl_elem_value *ucontrol)
435 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
436 hda_nid_t nid = kcontrol->private_value & 0xffff;
437 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
438 long *valp = ucontrol->value.integer.value;
439 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
440 AC_VERB_GET_PIN_WIDGET_CONTROL,
443 /* Find enumerated value for current pinctl setting */
444 i = alc_pin_mode_min(dir);
445 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
447 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
451 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
452 struct snd_ctl_elem_value *ucontrol)
455 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
456 hda_nid_t nid = kcontrol->private_value & 0xffff;
457 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
458 long val = *ucontrol->value.integer.value;
459 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
460 AC_VERB_GET_PIN_WIDGET_CONTROL,
463 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
464 val = alc_pin_mode_min(dir);
466 change = pinctl != alc_pin_mode_values[val];
468 /* Set pin mode to that requested */
469 snd_hda_codec_write_cache(codec, nid, 0,
470 AC_VERB_SET_PIN_WIDGET_CONTROL,
471 alc_pin_mode_values[val]);
473 /* Also enable the retasking pin's input/output as required
474 * for the requested pin mode. Enum values of 2 or less are
477 * Dynamically switching the input/output buffers probably
478 * reduces noise slightly (particularly on input) so we'll
479 * do it. However, having both input and output buffers
480 * enabled simultaneously doesn't seem to be problematic if
481 * this turns out to be necessary in the future.
484 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
485 HDA_AMP_MUTE, HDA_AMP_MUTE);
486 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
489 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
490 HDA_AMP_MUTE, HDA_AMP_MUTE);
491 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
498 #define ALC_PIN_MODE(xname, nid, dir) \
499 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
500 .info = alc_pin_mode_info, \
501 .get = alc_pin_mode_get, \
502 .put = alc_pin_mode_put, \
503 .private_value = nid | (dir<<16) }
505 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
506 * together using a mask with more than one bit set. This control is
507 * currently used only by the ALC260 test model. At this stage they are not
508 * needed for any "production" models.
510 #ifdef CONFIG_SND_DEBUG
511 #define alc_gpio_data_info snd_ctl_boolean_mono_info
513 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
514 struct snd_ctl_elem_value *ucontrol)
516 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
517 hda_nid_t nid = kcontrol->private_value & 0xffff;
518 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
519 long *valp = ucontrol->value.integer.value;
520 unsigned int val = snd_hda_codec_read(codec, nid, 0,
521 AC_VERB_GET_GPIO_DATA, 0x00);
523 *valp = (val & mask) != 0;
526 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
527 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 val = *ucontrol->value.integer.value;
534 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
535 AC_VERB_GET_GPIO_DATA,
538 /* Set/unset the masked GPIO bit(s) as needed */
539 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
544 snd_hda_codec_write_cache(codec, nid, 0,
545 AC_VERB_SET_GPIO_DATA, gpio_data);
549 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
550 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
551 .info = alc_gpio_data_info, \
552 .get = alc_gpio_data_get, \
553 .put = alc_gpio_data_put, \
554 .private_value = nid | (mask<<16) }
555 #endif /* CONFIG_SND_DEBUG */
557 /* A switch control to allow the enabling of the digital IO pins on the
558 * ALC260. This is incredibly simplistic; the intention of this control is
559 * to provide something in the test model allowing digital outputs to be
560 * identified if present. If models are found which can utilise these
561 * outputs a more complete mixer control can be devised for those models if
564 #ifdef CONFIG_SND_DEBUG
565 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
567 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
568 struct snd_ctl_elem_value *ucontrol)
570 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
571 hda_nid_t nid = kcontrol->private_value & 0xffff;
572 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
573 long *valp = ucontrol->value.integer.value;
574 unsigned int val = snd_hda_codec_read(codec, nid, 0,
575 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
577 *valp = (val & mask) != 0;
580 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
581 struct snd_ctl_elem_value *ucontrol)
584 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
585 hda_nid_t nid = kcontrol->private_value & 0xffff;
586 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
587 long val = *ucontrol->value.integer.value;
588 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
589 AC_VERB_GET_DIGI_CONVERT_1,
592 /* Set/unset the masked control bit(s) as needed */
593 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
598 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
603 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
604 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
605 .info = alc_spdif_ctrl_info, \
606 .get = alc_spdif_ctrl_get, \
607 .put = alc_spdif_ctrl_put, \
608 .private_value = nid | (mask<<16) }
609 #endif /* CONFIG_SND_DEBUG */
611 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
612 * Again, this is only used in the ALC26x test models to help identify when
613 * the EAPD line must be asserted for features to work.
615 #ifdef CONFIG_SND_DEBUG
616 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
618 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
619 struct snd_ctl_elem_value *ucontrol)
621 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
622 hda_nid_t nid = kcontrol->private_value & 0xffff;
623 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
624 long *valp = ucontrol->value.integer.value;
625 unsigned int val = snd_hda_codec_read(codec, nid, 0,
626 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
628 *valp = (val & mask) != 0;
632 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
633 struct snd_ctl_elem_value *ucontrol)
636 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
637 hda_nid_t nid = kcontrol->private_value & 0xffff;
638 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
639 long val = *ucontrol->value.integer.value;
640 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
641 AC_VERB_GET_EAPD_BTLENABLE,
644 /* Set/unset the masked control bit(s) as needed */
645 change = (!val ? 0 : mask) != (ctrl_data & mask);
650 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
656 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
657 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
658 .info = alc_eapd_ctrl_info, \
659 .get = alc_eapd_ctrl_get, \
660 .put = alc_eapd_ctrl_put, \
661 .private_value = nid | (mask<<16) }
662 #endif /* CONFIG_SND_DEBUG */
665 * set up from the preset table
667 static void setup_preset(struct alc_spec *spec,
668 const struct alc_config_preset *preset)
672 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
673 spec->mixers[spec->num_mixers++] = preset->mixers[i];
674 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
676 spec->init_verbs[spec->num_init_verbs++] =
677 preset->init_verbs[i];
679 spec->channel_mode = preset->channel_mode;
680 spec->num_channel_mode = preset->num_channel_mode;
681 spec->need_dac_fix = preset->need_dac_fix;
683 spec->multiout.max_channels = spec->channel_mode[0].channels;
685 spec->multiout.num_dacs = preset->num_dacs;
686 spec->multiout.dac_nids = preset->dac_nids;
687 spec->multiout.dig_out_nid = preset->dig_out_nid;
688 spec->multiout.hp_nid = preset->hp_nid;
690 spec->num_mux_defs = preset->num_mux_defs;
691 if (!spec->num_mux_defs)
692 spec->num_mux_defs = 1;
693 spec->input_mux = preset->input_mux;
695 spec->num_adc_nids = preset->num_adc_nids;
696 spec->adc_nids = preset->adc_nids;
697 spec->dig_in_nid = preset->dig_in_nid;
699 spec->unsol_event = preset->unsol_event;
700 spec->init_hook = preset->init_hook;
701 #ifdef CONFIG_SND_HDA_POWER_SAVE
702 spec->loopback.amplist = preset->loopbacks;
706 /* Enable GPIO mask and set output */
707 static struct hda_verb alc_gpio1_init_verbs[] = {
708 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
709 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
710 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
714 static struct hda_verb alc_gpio2_init_verbs[] = {
715 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
716 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
717 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
721 static struct hda_verb alc_gpio3_init_verbs[] = {
722 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
723 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
724 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
728 static void alc_sku_automute(struct hda_codec *codec)
730 struct alc_spec *spec = codec->spec;
732 unsigned int present;
733 unsigned int hp_nid = spec->autocfg.hp_pins[0];
734 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
736 /* need to execute and sync at first */
737 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
738 present = snd_hda_codec_read(codec, hp_nid, 0,
739 AC_VERB_GET_PIN_SENSE, 0);
740 spec->jack_present = (present & 0x80000000) != 0;
741 if (spec->jack_present) {
742 /* mute internal speaker */
743 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
744 HDA_AMP_MUTE, HDA_AMP_MUTE);
746 /* unmute internal speaker if necessary */
747 mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0);
748 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
753 /* unsolicited event for HP jack sensing */
754 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
756 if (codec->vendor_id == 0x10ec0880)
760 if (res != ALC880_HP_EVENT)
763 alc_sku_automute(codec);
766 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
767 * 31 ~ 16 : Manufacture ID
769 * 7 ~ 0 : Assembly ID
770 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
772 static void alc_subsystem_id(struct hda_codec *codec,
773 unsigned int porta, unsigned int porte,
776 unsigned int ass, tmp, i;
778 struct alc_spec *spec = codec->spec;
780 ass = codec->subsystem_id & 0xffff;
781 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
785 * 31~30 : port conetcivity
788 * 19~16 : Check sum (15:1)
793 if (codec->vendor_id == 0x10ec0260)
795 ass = snd_hda_codec_read(codec, nid, 0,
796 AC_VERB_GET_CONFIG_DEFAULT, 0);
797 if (!(ass & 1) && !(ass & 0x100000))
799 if ((ass >> 30) != 1) /* no physical connection */
804 for (i = 1; i < 16; i++) {
808 if (((ass >> 16) & 0xf) != tmp)
814 * 2 : 0 --> Desktop, 1 --> Laptop
815 * 3~5 : External Amplifier control
818 tmp = (ass & 0x38) >> 3; /* external Amp control */
821 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
824 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
827 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
829 case 5: /* set EAPD output high */
830 switch (codec->vendor_id) {
832 snd_hda_codec_write(codec, 0x0f, 0,
833 AC_VERB_SET_EAPD_BTLENABLE, 2);
834 snd_hda_codec_write(codec, 0x10, 0,
835 AC_VERB_SET_EAPD_BTLENABLE, 2);
843 snd_hda_codec_write(codec, 0x14, 0,
844 AC_VERB_SET_EAPD_BTLENABLE, 2);
845 snd_hda_codec_write(codec, 0x15, 0,
846 AC_VERB_SET_EAPD_BTLENABLE, 2);
849 switch (codec->vendor_id) {
851 snd_hda_codec_write(codec, 0x1a, 0,
852 AC_VERB_SET_COEF_INDEX, 7);
853 tmp = snd_hda_codec_read(codec, 0x1a, 0,
854 AC_VERB_GET_PROC_COEF, 0);
855 snd_hda_codec_write(codec, 0x1a, 0,
856 AC_VERB_SET_COEF_INDEX, 7);
857 snd_hda_codec_write(codec, 0x1a, 0,
858 AC_VERB_SET_PROC_COEF,
867 snd_hda_codec_write(codec, 0x20, 0,
868 AC_VERB_SET_COEF_INDEX, 7);
869 tmp = snd_hda_codec_read(codec, 0x20, 0,
870 AC_VERB_GET_PROC_COEF, 0);
871 snd_hda_codec_write(codec, 0x20, 0,
872 AC_VERB_SET_COEF_INDEX, 7);
873 snd_hda_codec_write(codec, 0x20, 0,
874 AC_VERB_SET_PROC_COEF,
879 snd_hda_codec_write(codec, 0x20, 0,
880 AC_VERB_SET_COEF_INDEX, 7);
881 tmp = snd_hda_codec_read(codec, 0x20, 0,
882 AC_VERB_GET_PROC_COEF, 0);
883 snd_hda_codec_write(codec, 0x20, 0,
884 AC_VERB_SET_COEF_INDEX, 7);
885 snd_hda_codec_write(codec, 0x20, 0,
886 AC_VERB_SET_PROC_COEF,
894 /* is laptop and enable the function "Mute internal speaker
895 * when the external headphone out jack is plugged"
897 if (!(ass & 0x4) || !(ass & 0x8000))
900 * 10~8 : Jack location
901 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
903 * 15 : 1 --> enable the function "Mute internal speaker
904 * when the external headphone out jack is plugged"
906 if (!spec->autocfg.speaker_pins[0]) {
907 if (spec->multiout.dac_nids[0])
908 spec->autocfg.speaker_pins[0] =
909 spec->multiout.dac_nids[0];
914 if (!spec->autocfg.hp_pins[0]) {
915 tmp = (ass >> 11) & 0x3; /* HP to chassis */
917 spec->autocfg.hp_pins[0] = porta;
919 spec->autocfg.hp_pins[0] = porte;
921 spec->autocfg.hp_pins[0] = portd;
926 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
927 AC_VERB_SET_UNSOLICITED_ENABLE,
928 AC_USRSP_EN | ALC880_HP_EVENT);
929 spec->unsol_event = alc_sku_unsol_event;
930 spec->init_hook = alc_sku_automute;
934 * Fix-up pin default configurations
942 static void alc_fix_pincfg(struct hda_codec *codec,
943 const struct snd_pci_quirk *quirk,
944 const struct alc_pincfg **pinfix)
946 const struct alc_pincfg *cfg;
948 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
952 cfg = pinfix[quirk->value];
953 for (; cfg->nid; cfg++) {
956 for (i = 0; i < 4; i++) {
957 snd_hda_codec_write(codec, cfg->nid, 0,
958 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
966 * ALC880 3-stack model
968 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
969 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
970 * F-Mic = 0x1b, HP = 0x19
973 static hda_nid_t alc880_dac_nids[4] = {
974 /* front, rear, clfe, rear_surr */
975 0x02, 0x05, 0x04, 0x03
978 static hda_nid_t alc880_adc_nids[3] = {
983 /* The datasheet says the node 0x07 is connected from inputs,
984 * but it shows zero connection in the real implementation on some devices.
985 * Note: this is a 915GAV bug, fixed on 915GLV
987 static hda_nid_t alc880_adc_nids_alt[2] = {
992 #define ALC880_DIGOUT_NID 0x06
993 #define ALC880_DIGIN_NID 0x0a
995 static struct hda_input_mux alc880_capture_source = {
999 { "Front Mic", 0x3 },
1005 /* channel source setting (2/6 channel selection for 3-stack) */
1007 static struct hda_verb alc880_threestack_ch2_init[] = {
1008 /* set line-in to input, mute it */
1009 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1010 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1011 /* set mic-in to input vref 80%, mute it */
1012 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1013 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1018 static struct hda_verb alc880_threestack_ch6_init[] = {
1019 /* set line-in to output, unmute it */
1020 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1021 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1022 /* set mic-in to output, unmute it */
1023 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1024 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1028 static struct hda_channel_mode alc880_threestack_modes[2] = {
1029 { 2, alc880_threestack_ch2_init },
1030 { 6, alc880_threestack_ch6_init },
1033 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1034 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1035 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1036 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1037 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1038 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1039 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1040 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1041 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1042 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1043 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1044 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1045 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1046 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1047 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1048 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1049 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1050 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1051 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1052 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1054 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1055 .name = "Channel Mode",
1056 .info = alc_ch_mode_info,
1057 .get = alc_ch_mode_get,
1058 .put = alc_ch_mode_put,
1063 /* capture mixer elements */
1064 static struct snd_kcontrol_new alc880_capture_mixer[] = {
1065 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1066 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1067 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1068 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1069 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1070 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1072 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1073 /* The multiple "Capture Source" controls confuse alsamixer
1074 * So call somewhat different..
1075 * FIXME: the controls appear in the "playback" view!
1077 /* .name = "Capture Source", */
1078 .name = "Input Source",
1080 .info = alc_mux_enum_info,
1081 .get = alc_mux_enum_get,
1082 .put = alc_mux_enum_put,
1087 /* capture mixer elements (in case NID 0x07 not available) */
1088 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1089 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1090 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1091 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1092 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1094 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1095 /* The multiple "Capture Source" controls confuse alsamixer
1096 * So call somewhat different..
1097 * FIXME: the controls appear in the "playback" view!
1099 /* .name = "Capture Source", */
1100 .name = "Input Source",
1102 .info = alc_mux_enum_info,
1103 .get = alc_mux_enum_get,
1104 .put = alc_mux_enum_put,
1112 * ALC880 5-stack model
1114 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1116 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1117 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1120 /* additional mixers to alc880_three_stack_mixer */
1121 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1122 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1123 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1127 /* channel source setting (6/8 channel selection for 5-stack) */
1129 static struct hda_verb alc880_fivestack_ch6_init[] = {
1130 /* set line-in to input, mute it */
1131 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1132 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1137 static struct hda_verb alc880_fivestack_ch8_init[] = {
1138 /* set line-in to output, unmute it */
1139 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1140 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1144 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1145 { 6, alc880_fivestack_ch6_init },
1146 { 8, alc880_fivestack_ch8_init },
1151 * ALC880 6-stack model
1153 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1154 * Side = 0x05 (0x0f)
1155 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1156 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1159 static hda_nid_t alc880_6st_dac_nids[4] = {
1160 /* front, rear, clfe, rear_surr */
1161 0x02, 0x03, 0x04, 0x05
1164 static struct hda_input_mux alc880_6stack_capture_source = {
1168 { "Front Mic", 0x1 },
1174 /* fixed 8-channels */
1175 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1179 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1180 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1181 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1182 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1183 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1184 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1185 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1186 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1187 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1188 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1189 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1190 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1191 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1192 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1193 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1194 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1195 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1196 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1197 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1198 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1199 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1201 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1202 .name = "Channel Mode",
1203 .info = alc_ch_mode_info,
1204 .get = alc_ch_mode_get,
1205 .put = alc_ch_mode_put,
1214 * W810 has rear IO for:
1217 * Center/LFE (DAC 04)
1220 * The system also has a pair of internal speakers, and a headphone jack.
1221 * These are both connected to Line2 on the codec, hence to DAC 02.
1223 * There is a variable resistor to control the speaker or headphone
1224 * volume. This is a hardware-only device without a software API.
1226 * Plugging headphones in will disable the internal speakers. This is
1227 * implemented in hardware, not via the driver using jack sense. In
1228 * a similar fashion, plugging into the rear socket marked "front" will
1229 * disable both the speakers and headphones.
1231 * For input, there's a microphone jack, and an "audio in" jack.
1232 * These may not do anything useful with this driver yet, because I
1233 * haven't setup any initialization verbs for these yet...
1236 static hda_nid_t alc880_w810_dac_nids[3] = {
1237 /* front, rear/surround, clfe */
1241 /* fixed 6 channels */
1242 static struct hda_channel_mode alc880_w810_modes[1] = {
1246 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1247 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1248 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1249 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1250 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1251 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1252 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1253 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1254 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1255 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1256 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1264 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1265 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1269 static hda_nid_t alc880_z71v_dac_nids[1] = {
1272 #define ALC880_Z71V_HP_DAC 0x03
1274 /* fixed 2 channels */
1275 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1279 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1280 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1281 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1282 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1283 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1284 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1285 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1286 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1287 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1294 * ALC880 F1734 model
1296 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1297 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1300 static hda_nid_t alc880_f1734_dac_nids[1] = {
1303 #define ALC880_F1734_HP_DAC 0x02
1305 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1306 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1307 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1308 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1309 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1310 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1311 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1312 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1313 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1322 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1323 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1324 * Mic = 0x18, Line = 0x1a
1327 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1328 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1330 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1331 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1332 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1333 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1334 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1335 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1336 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1337 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1338 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1339 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1340 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1341 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1342 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1343 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1344 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1346 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1347 .name = "Channel Mode",
1348 .info = alc_ch_mode_info,
1349 .get = alc_ch_mode_get,
1350 .put = alc_ch_mode_put,
1357 * ALC880 ASUS W1V model
1359 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1360 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1361 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1364 /* additional mixers to alc880_asus_mixer */
1365 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1366 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1367 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1371 /* additional mixers to alc880_asus_mixer */
1372 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1373 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1374 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1379 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1380 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1381 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1383 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1384 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1385 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1386 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1387 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1388 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1390 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1391 /* The multiple "Capture Source" controls confuse alsamixer
1392 * So call somewhat different..
1393 * FIXME: the controls appear in the "playback" view!
1395 /* .name = "Capture Source", */
1396 .name = "Input Source",
1398 .info = alc_mux_enum_info,
1399 .get = alc_mux_enum_get,
1400 .put = alc_mux_enum_put,
1406 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1407 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1408 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1409 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1410 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1411 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1412 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1413 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1414 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1415 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1416 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1417 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1418 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1419 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1420 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1421 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1422 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1423 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1424 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1426 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1427 .name = "Channel Mode",
1428 .info = alc_ch_mode_info,
1429 .get = alc_ch_mode_get,
1430 .put = alc_ch_mode_put,
1435 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1436 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1437 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1438 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1439 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1440 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1441 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1442 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1443 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1444 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1445 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1449 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1450 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1451 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1452 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1453 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1454 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1455 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1460 * build control elements
1462 static int alc_build_controls(struct hda_codec *codec)
1464 struct alc_spec *spec = codec->spec;
1468 for (i = 0; i < spec->num_mixers; i++) {
1469 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1474 if (spec->multiout.dig_out_nid) {
1475 err = snd_hda_create_spdif_out_ctls(codec,
1476 spec->multiout.dig_out_nid);
1480 if (spec->dig_in_nid) {
1481 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1490 * initialize the codec volumes, etc
1494 * generic initialization of ADC, input mixers and output mixers
1496 static struct hda_verb alc880_volume_init_verbs[] = {
1498 * Unmute ADC0-2 and set the default input to mic-in
1500 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1502 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1503 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1504 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1505 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1507 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1509 * Note: PASD motherboards uses the Line In 2 as the input for front
1512 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1513 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1514 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1515 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1516 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1517 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1518 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1519 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1522 * Set up output mixers (0x0c - 0x0f)
1524 /* set vol=0 to output mixers */
1525 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1526 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1527 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1528 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1529 /* set up input amps for analog loopback */
1530 /* Amp Indices: DAC = 0, mixer = 1 */
1531 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1532 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1533 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1534 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1535 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1536 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1537 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1538 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1544 * 3-stack pin configuration:
1545 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1547 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1549 * preset connection lists of input pins
1550 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1552 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1553 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1554 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1557 * Set pin mode and muting
1559 /* set front pin widgets 0x14 for output */
1560 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1561 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1562 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1563 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1564 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1565 /* Mic2 (as headphone out) for HP output */
1566 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1567 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1568 /* Line In pin widget for input */
1569 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1570 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1571 /* Line2 (as front mic) pin widget for input and vref at 80% */
1572 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1573 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1574 /* CD pin widget for input */
1575 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1581 * 5-stack pin configuration:
1582 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1583 * line-in/side = 0x1a, f-mic = 0x1b
1585 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1587 * preset connection lists of input pins
1588 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1590 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1591 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1594 * Set pin mode and muting
1596 /* set pin widgets 0x14-0x17 for output */
1597 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1598 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1599 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1600 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1601 /* unmute pins for output (no gain on this amp) */
1602 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1603 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1604 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1605 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1607 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1608 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1609 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1610 /* Mic2 (as headphone out) for HP output */
1611 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1612 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1613 /* Line In pin widget for input */
1614 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1615 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1616 /* Line2 (as front mic) pin widget for input and vref at 80% */
1617 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1618 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1619 /* CD pin widget for input */
1620 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1626 * W810 pin configuration:
1627 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1629 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1630 /* hphone/speaker input selector: front DAC */
1631 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1633 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1634 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1635 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1636 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1637 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1638 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1640 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1641 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1647 * Z71V pin configuration:
1648 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1650 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1651 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1652 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1653 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1654 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1656 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1657 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1658 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1659 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1665 * 6-stack pin configuration:
1666 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1667 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1669 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1670 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1672 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1673 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1674 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1675 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1676 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1677 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1678 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1679 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1681 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1682 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1683 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1684 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1685 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1686 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1687 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1688 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1689 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1695 * Uniwill pin configuration:
1696 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1699 static struct hda_verb alc880_uniwill_init_verbs[] = {
1700 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1702 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1703 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1704 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1705 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1706 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1707 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1708 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1709 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1710 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1711 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1712 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1713 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1714 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1715 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1717 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1718 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1719 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1720 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1721 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1722 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1723 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1724 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1725 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1727 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1728 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1735 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1737 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1738 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1740 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1741 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1742 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1743 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1744 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1745 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1747 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1748 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1749 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1750 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1751 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1753 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1754 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1755 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1756 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1757 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1758 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1760 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1761 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1766 static struct hda_verb alc880_beep_init_verbs[] = {
1767 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1771 /* toggle speaker-output according to the hp-jack state */
1772 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1774 unsigned int present;
1777 present = snd_hda_codec_read(codec, 0x14, 0,
1778 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1779 bits = present ? HDA_AMP_MUTE : 0;
1780 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1781 HDA_AMP_MUTE, bits);
1782 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1783 HDA_AMP_MUTE, bits);
1786 /* auto-toggle front mic */
1787 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1789 unsigned int present;
1792 present = snd_hda_codec_read(codec, 0x18, 0,
1793 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1794 bits = present ? HDA_AMP_MUTE : 0;
1795 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1798 static void alc880_uniwill_automute(struct hda_codec *codec)
1800 alc880_uniwill_hp_automute(codec);
1801 alc880_uniwill_mic_automute(codec);
1804 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1807 /* Looks like the unsol event is incompatible with the standard
1808 * definition. 4bit tag is placed at 28 bit!
1810 switch (res >> 28) {
1811 case ALC880_HP_EVENT:
1812 alc880_uniwill_hp_automute(codec);
1814 case ALC880_MIC_EVENT:
1815 alc880_uniwill_mic_automute(codec);
1820 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1822 unsigned int present;
1825 present = snd_hda_codec_read(codec, 0x14, 0,
1826 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1827 bits = present ? HDA_AMP_MUTE : 0;
1828 snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1831 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1833 unsigned int present;
1835 present = snd_hda_codec_read(codec, 0x21, 0,
1836 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1837 present &= HDA_AMP_VOLMASK;
1838 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1839 HDA_AMP_VOLMASK, present);
1840 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1841 HDA_AMP_VOLMASK, present);
1844 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1847 /* Looks like the unsol event is incompatible with the standard
1848 * definition. 4bit tag is placed at 28 bit!
1850 if ((res >> 28) == ALC880_HP_EVENT)
1851 alc880_uniwill_p53_hp_automute(codec);
1852 if ((res >> 28) == ALC880_DCVOL_EVENT)
1853 alc880_uniwill_p53_dcvol_automute(codec);
1858 * F1734 pin configuration:
1859 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1861 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1862 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1863 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1864 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1865 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1867 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1868 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1869 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1870 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1872 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1873 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1874 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1875 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1876 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1877 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1878 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1879 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1880 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1887 * ASUS pin configuration:
1888 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1890 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1891 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1892 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1893 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1894 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1896 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1897 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1898 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1899 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1900 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1901 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1902 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1903 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1905 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1906 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1907 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1908 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1909 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1910 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1911 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1912 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1913 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1918 /* Enable GPIO mask and set output */
1919 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1920 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1922 /* Clevo m520g init */
1923 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1924 /* headphone output */
1925 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1927 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1928 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1930 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1931 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1933 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1934 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1935 /* Mic1 (rear panel) */
1936 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1937 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1938 /* Mic2 (front panel) */
1939 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1940 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1942 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1943 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1944 /* change to EAPD mode */
1945 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1946 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
1951 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1952 /* change to EAPD mode */
1953 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1954 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
1956 /* Headphone output */
1957 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1959 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1960 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1962 /* Line In pin widget for input */
1963 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1964 /* CD pin widget for input */
1965 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1966 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1967 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1969 /* change to EAPD mode */
1970 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1971 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
1977 * LG m1 express dual
1980 * Rear Line-In/Out (blue): 0x14
1981 * Build-in Mic-In: 0x15
1983 * HP-Out (green): 0x1b
1984 * Mic-In/Out (red): 0x19
1988 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1989 static hda_nid_t alc880_lg_dac_nids[3] = {
1993 /* seems analog CD is not working */
1994 static struct hda_input_mux alc880_lg_capture_source = {
1999 { "Internal Mic", 0x6 },
2003 /* 2,4,6 channel modes */
2004 static struct hda_verb alc880_lg_ch2_init[] = {
2005 /* set line-in and mic-in to input */
2006 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2007 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2011 static struct hda_verb alc880_lg_ch4_init[] = {
2012 /* set line-in to out and mic-in to input */
2013 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2014 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2018 static struct hda_verb alc880_lg_ch6_init[] = {
2019 /* set line-in and mic-in to output */
2020 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2021 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2025 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2026 { 2, alc880_lg_ch2_init },
2027 { 4, alc880_lg_ch4_init },
2028 { 6, alc880_lg_ch6_init },
2031 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2032 /* FIXME: it's not really "master" but front channels */
2033 HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2034 HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
2035 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2036 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2037 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2038 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2039 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2040 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2041 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2042 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2043 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2044 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2045 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2046 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2048 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2049 .name = "Channel Mode",
2050 .info = alc_ch_mode_info,
2051 .get = alc_ch_mode_get,
2052 .put = alc_ch_mode_put,
2057 static struct hda_verb alc880_lg_init_verbs[] = {
2058 /* set capture source to mic-in */
2059 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2060 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2061 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2062 /* mute all amp mixer inputs */
2063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2065 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2066 /* line-in to input */
2067 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2068 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2070 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2071 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2073 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2074 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2075 /* mic-in to input */
2076 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2077 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2078 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2080 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2081 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2082 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2084 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2088 /* toggle speaker-output according to the hp-jack state */
2089 static void alc880_lg_automute(struct hda_codec *codec)
2091 unsigned int present;
2094 present = snd_hda_codec_read(codec, 0x1b, 0,
2095 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2096 bits = present ? HDA_AMP_MUTE : 0;
2097 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2098 HDA_AMP_MUTE, bits);
2101 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2103 /* Looks like the unsol event is incompatible with the standard
2104 * definition. 4bit tag is placed at 28 bit!
2106 if ((res >> 28) == 0x01)
2107 alc880_lg_automute(codec);
2116 * Built-in Mic-In: 0x19
2122 static struct hda_input_mux alc880_lg_lw_capture_source = {
2126 { "Internal Mic", 0x1 },
2131 #define alc880_lg_lw_modes alc880_threestack_modes
2133 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2134 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2135 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2136 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2137 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2138 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2139 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2140 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2141 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2142 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2143 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2144 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2146 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2147 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2149 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2150 .name = "Channel Mode",
2151 .info = alc_ch_mode_info,
2152 .get = alc_ch_mode_get,
2153 .put = alc_ch_mode_put,
2158 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2159 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2160 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2161 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2163 /* set capture source to mic-in */
2164 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2165 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2166 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2167 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2169 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2170 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2172 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2173 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2174 /* mic-in to input */
2175 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2176 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2178 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2179 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2181 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2185 /* toggle speaker-output according to the hp-jack state */
2186 static void alc880_lg_lw_automute(struct hda_codec *codec)
2188 unsigned int present;
2191 present = snd_hda_codec_read(codec, 0x1b, 0,
2192 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2193 bits = present ? HDA_AMP_MUTE : 0;
2194 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2195 HDA_AMP_MUTE, bits);
2198 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2200 /* Looks like the unsol event is incompatible with the standard
2201 * definition. 4bit tag is placed at 28 bit!
2203 if ((res >> 28) == 0x01)
2204 alc880_lg_lw_automute(codec);
2207 #ifdef CONFIG_SND_HDA_POWER_SAVE
2208 static struct hda_amp_list alc880_loopbacks[] = {
2209 { 0x0b, HDA_INPUT, 0 },
2210 { 0x0b, HDA_INPUT, 1 },
2211 { 0x0b, HDA_INPUT, 2 },
2212 { 0x0b, HDA_INPUT, 3 },
2213 { 0x0b, HDA_INPUT, 4 },
2217 static struct hda_amp_list alc880_lg_loopbacks[] = {
2218 { 0x0b, HDA_INPUT, 1 },
2219 { 0x0b, HDA_INPUT, 6 },
2220 { 0x0b, HDA_INPUT, 7 },
2229 static int alc_init(struct hda_codec *codec)
2231 struct alc_spec *spec = codec->spec;
2234 for (i = 0; i < spec->num_init_verbs; i++)
2235 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2237 if (spec->init_hook)
2238 spec->init_hook(codec);
2243 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2245 struct alc_spec *spec = codec->spec;
2247 if (spec->unsol_event)
2248 spec->unsol_event(codec, res);
2251 #ifdef CONFIG_SND_HDA_POWER_SAVE
2252 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2254 struct alc_spec *spec = codec->spec;
2255 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2260 * Analog playback callbacks
2262 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2263 struct hda_codec *codec,
2264 struct snd_pcm_substream *substream)
2266 struct alc_spec *spec = codec->spec;
2267 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2270 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2271 struct hda_codec *codec,
2272 unsigned int stream_tag,
2273 unsigned int format,
2274 struct snd_pcm_substream *substream)
2276 struct alc_spec *spec = codec->spec;
2277 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2278 stream_tag, format, substream);
2281 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2282 struct hda_codec *codec,
2283 struct snd_pcm_substream *substream)
2285 struct alc_spec *spec = codec->spec;
2286 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2292 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2293 struct hda_codec *codec,
2294 struct snd_pcm_substream *substream)
2296 struct alc_spec *spec = codec->spec;
2297 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2300 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2301 struct hda_codec *codec,
2302 unsigned int stream_tag,
2303 unsigned int format,
2304 struct snd_pcm_substream *substream)
2306 struct alc_spec *spec = codec->spec;
2307 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2308 stream_tag, format, substream);
2311 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2312 struct hda_codec *codec,
2313 struct snd_pcm_substream *substream)
2315 struct alc_spec *spec = codec->spec;
2316 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2322 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2323 struct hda_codec *codec,
2324 unsigned int stream_tag,
2325 unsigned int format,
2326 struct snd_pcm_substream *substream)
2328 struct alc_spec *spec = codec->spec;
2330 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2331 stream_tag, 0, format);
2335 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2336 struct hda_codec *codec,
2337 struct snd_pcm_substream *substream)
2339 struct alc_spec *spec = codec->spec;
2341 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2349 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2353 /* NID is set in alc_build_pcms */
2355 .open = alc880_playback_pcm_open,
2356 .prepare = alc880_playback_pcm_prepare,
2357 .cleanup = alc880_playback_pcm_cleanup
2361 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2365 /* NID is set in alc_build_pcms */
2367 .prepare = alc880_capture_pcm_prepare,
2368 .cleanup = alc880_capture_pcm_cleanup
2372 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2376 /* NID is set in alc_build_pcms */
2378 .open = alc880_dig_playback_pcm_open,
2379 .close = alc880_dig_playback_pcm_close,
2380 .prepare = alc880_dig_playback_pcm_prepare
2384 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2388 /* NID is set in alc_build_pcms */
2391 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2392 static struct hda_pcm_stream alc_pcm_null_playback = {
2398 static int alc_build_pcms(struct hda_codec *codec)
2400 struct alc_spec *spec = codec->spec;
2401 struct hda_pcm *info = spec->pcm_rec;
2404 codec->num_pcms = 1;
2405 codec->pcm_info = info;
2407 info->name = spec->stream_name_analog;
2408 if (spec->stream_analog_playback) {
2409 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2410 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2411 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2413 if (spec->stream_analog_capture) {
2414 snd_assert(spec->adc_nids, return -EINVAL);
2415 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2416 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2419 if (spec->channel_mode) {
2420 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2421 for (i = 0; i < spec->num_channel_mode; i++) {
2422 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2423 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2428 /* SPDIF for stream index #1 */
2429 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2430 codec->num_pcms = 2;
2431 info = spec->pcm_rec + 1;
2432 info->name = spec->stream_name_digital;
2433 if (spec->multiout.dig_out_nid &&
2434 spec->stream_digital_playback) {
2435 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2436 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2438 if (spec->dig_in_nid &&
2439 spec->stream_digital_capture) {
2440 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2441 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2445 /* If the use of more than one ADC is requested for the current
2446 * model, configure a second analog capture-only PCM.
2448 /* Additional Analaog capture for index #2 */
2449 if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2451 codec->num_pcms = 3;
2452 info = spec->pcm_rec + 2;
2453 info->name = spec->stream_name_analog;
2454 /* No playback stream for second PCM */
2455 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2456 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2457 if (spec->stream_analog_capture) {
2458 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2459 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2466 static void alc_free(struct hda_codec *codec)
2468 struct alc_spec *spec = codec->spec;
2474 if (spec->kctl_alloc) {
2475 for (i = 0; i < spec->num_kctl_used; i++)
2476 kfree(spec->kctl_alloc[i].name);
2477 kfree(spec->kctl_alloc);
2484 static struct hda_codec_ops alc_patch_ops = {
2485 .build_controls = alc_build_controls,
2486 .build_pcms = alc_build_pcms,
2489 .unsol_event = alc_unsol_event,
2490 #ifdef CONFIG_SND_HDA_POWER_SAVE
2491 .check_power_status = alc_check_power_status,
2497 * Test configuration for debugging
2499 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2502 #ifdef CONFIG_SND_DEBUG
2503 static hda_nid_t alc880_test_dac_nids[4] = {
2504 0x02, 0x03, 0x04, 0x05
2507 static struct hda_input_mux alc880_test_capture_source = {
2516 { "Surround", 0x6 },
2520 static struct hda_channel_mode alc880_test_modes[4] = {
2527 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2528 struct snd_ctl_elem_info *uinfo)
2530 static char *texts[] = {
2531 "N/A", "Line Out", "HP Out",
2532 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2534 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2536 uinfo->value.enumerated.items = 8;
2537 if (uinfo->value.enumerated.item >= 8)
2538 uinfo->value.enumerated.item = 7;
2539 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2543 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2544 struct snd_ctl_elem_value *ucontrol)
2546 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2547 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2548 unsigned int pin_ctl, item = 0;
2550 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2551 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2552 if (pin_ctl & AC_PINCTL_OUT_EN) {
2553 if (pin_ctl & AC_PINCTL_HP_EN)
2557 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2558 switch (pin_ctl & AC_PINCTL_VREFEN) {
2559 case AC_PINCTL_VREF_HIZ: item = 3; break;
2560 case AC_PINCTL_VREF_50: item = 4; break;
2561 case AC_PINCTL_VREF_GRD: item = 5; break;
2562 case AC_PINCTL_VREF_80: item = 6; break;
2563 case AC_PINCTL_VREF_100: item = 7; break;
2566 ucontrol->value.enumerated.item[0] = item;
2570 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2571 struct snd_ctl_elem_value *ucontrol)
2573 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2574 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2575 static unsigned int ctls[] = {
2576 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2577 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2578 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2579 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2580 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2581 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2583 unsigned int old_ctl, new_ctl;
2585 old_ctl = snd_hda_codec_read(codec, nid, 0,
2586 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2587 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2588 if (old_ctl != new_ctl) {
2590 snd_hda_codec_write_cache(codec, nid, 0,
2591 AC_VERB_SET_PIN_WIDGET_CONTROL,
2593 val = ucontrol->value.enumerated.item[0] >= 3 ?
2595 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2602 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2603 struct snd_ctl_elem_info *uinfo)
2605 static char *texts[] = {
2606 "Front", "Surround", "CLFE", "Side"
2608 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2610 uinfo->value.enumerated.items = 4;
2611 if (uinfo->value.enumerated.item >= 4)
2612 uinfo->value.enumerated.item = 3;
2613 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2617 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2618 struct snd_ctl_elem_value *ucontrol)
2620 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2621 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2624 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2625 ucontrol->value.enumerated.item[0] = sel & 3;
2629 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2630 struct snd_ctl_elem_value *ucontrol)
2632 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2633 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2636 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2637 if (ucontrol->value.enumerated.item[0] != sel) {
2638 sel = ucontrol->value.enumerated.item[0] & 3;
2639 snd_hda_codec_write_cache(codec, nid, 0,
2640 AC_VERB_SET_CONNECT_SEL, sel);
2646 #define PIN_CTL_TEST(xname,nid) { \
2647 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2649 .info = alc_test_pin_ctl_info, \
2650 .get = alc_test_pin_ctl_get, \
2651 .put = alc_test_pin_ctl_put, \
2652 .private_value = nid \
2655 #define PIN_SRC_TEST(xname,nid) { \
2656 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2658 .info = alc_test_pin_src_info, \
2659 .get = alc_test_pin_src_get, \
2660 .put = alc_test_pin_src_put, \
2661 .private_value = nid \
2664 static struct snd_kcontrol_new alc880_test_mixer[] = {
2665 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2666 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2667 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2668 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2669 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2670 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2671 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2672 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2673 PIN_CTL_TEST("Front Pin Mode", 0x14),
2674 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2675 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2676 PIN_CTL_TEST("Side Pin Mode", 0x17),
2677 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2678 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2679 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2680 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2681 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2682 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2683 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2684 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2685 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2686 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2687 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2688 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2689 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2690 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2691 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2692 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2693 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2694 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2696 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2697 .name = "Channel Mode",
2698 .info = alc_ch_mode_info,
2699 .get = alc_ch_mode_get,
2700 .put = alc_ch_mode_put,
2705 static struct hda_verb alc880_test_init_verbs[] = {
2706 /* Unmute inputs of 0x0c - 0x0f */
2707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2708 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2709 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2710 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2711 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2712 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2713 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2714 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2715 /* Vol output for 0x0c-0x0f */
2716 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2717 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2718 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2719 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2720 /* Set output pins 0x14-0x17 */
2721 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2722 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2723 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2724 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2725 /* Unmute output pins 0x14-0x17 */
2726 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2727 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2728 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2729 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2730 /* Set input pins 0x18-0x1c */
2731 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2732 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2733 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2734 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2735 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2736 /* Mute input pins 0x18-0x1b */
2737 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2738 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2739 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2740 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2742 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2743 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2744 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2745 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2746 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2747 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2748 /* Analog input/passthru */
2749 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2750 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2751 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2752 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2753 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2761 static const char *alc880_models[ALC880_MODEL_LAST] = {
2762 [ALC880_3ST] = "3stack",
2763 [ALC880_TCL_S700] = "tcl",
2764 [ALC880_3ST_DIG] = "3stack-digout",
2765 [ALC880_CLEVO] = "clevo",
2766 [ALC880_5ST] = "5stack",
2767 [ALC880_5ST_DIG] = "5stack-digout",
2768 [ALC880_W810] = "w810",
2769 [ALC880_Z71V] = "z71v",
2770 [ALC880_6ST] = "6stack",
2771 [ALC880_6ST_DIG] = "6stack-digout",
2772 [ALC880_ASUS] = "asus",
2773 [ALC880_ASUS_W1V] = "asus-w1v",
2774 [ALC880_ASUS_DIG] = "asus-dig",
2775 [ALC880_ASUS_DIG2] = "asus-dig2",
2776 [ALC880_UNIWILL_DIG] = "uniwill",
2777 [ALC880_UNIWILL_P53] = "uniwill-p53",
2778 [ALC880_FUJITSU] = "fujitsu",
2779 [ALC880_F1734] = "F1734",
2781 [ALC880_LG_LW] = "lg-lw",
2782 #ifdef CONFIG_SND_DEBUG
2783 [ALC880_TEST] = "test",
2785 [ALC880_AUTO] = "auto",
2788 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2789 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2790 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2791 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2792 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2793 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2794 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2795 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2796 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2797 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2798 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2799 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2800 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2801 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2802 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2803 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2804 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2805 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2806 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2807 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2808 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2809 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2810 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2811 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2812 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2813 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2814 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
2815 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2816 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2817 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2818 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2819 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2820 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2821 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2822 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2823 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2824 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2825 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2826 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2827 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2828 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2829 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2830 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2831 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2832 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2833 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2834 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2835 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2836 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2837 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2838 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2839 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2840 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2841 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2842 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2843 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
2844 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2845 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2846 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2847 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2848 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2849 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2850 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2851 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2852 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2853 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2854 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2855 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
2856 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2857 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2862 * ALC880 codec presets
2864 static struct alc_config_preset alc880_presets[] = {
2866 .mixers = { alc880_three_stack_mixer },
2867 .init_verbs = { alc880_volume_init_verbs,
2868 alc880_pin_3stack_init_verbs },
2869 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2870 .dac_nids = alc880_dac_nids,
2871 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2872 .channel_mode = alc880_threestack_modes,
2874 .input_mux = &alc880_capture_source,
2876 [ALC880_3ST_DIG] = {
2877 .mixers = { alc880_three_stack_mixer },
2878 .init_verbs = { alc880_volume_init_verbs,
2879 alc880_pin_3stack_init_verbs },
2880 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2881 .dac_nids = alc880_dac_nids,
2882 .dig_out_nid = ALC880_DIGOUT_NID,
2883 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2884 .channel_mode = alc880_threestack_modes,
2886 .input_mux = &alc880_capture_source,
2888 [ALC880_TCL_S700] = {
2889 .mixers = { alc880_tcl_s700_mixer },
2890 .init_verbs = { alc880_volume_init_verbs,
2891 alc880_pin_tcl_S700_init_verbs,
2892 alc880_gpio2_init_verbs },
2893 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2894 .dac_nids = alc880_dac_nids,
2896 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2897 .channel_mode = alc880_2_jack_modes,
2898 .input_mux = &alc880_capture_source,
2901 .mixers = { alc880_three_stack_mixer,
2902 alc880_five_stack_mixer},
2903 .init_verbs = { alc880_volume_init_verbs,
2904 alc880_pin_5stack_init_verbs },
2905 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2906 .dac_nids = alc880_dac_nids,
2907 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2908 .channel_mode = alc880_fivestack_modes,
2909 .input_mux = &alc880_capture_source,
2911 [ALC880_5ST_DIG] = {
2912 .mixers = { alc880_three_stack_mixer,
2913 alc880_five_stack_mixer },
2914 .init_verbs = { alc880_volume_init_verbs,
2915 alc880_pin_5stack_init_verbs },
2916 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2917 .dac_nids = alc880_dac_nids,
2918 .dig_out_nid = ALC880_DIGOUT_NID,
2919 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2920 .channel_mode = alc880_fivestack_modes,
2921 .input_mux = &alc880_capture_source,
2924 .mixers = { alc880_six_stack_mixer },
2925 .init_verbs = { alc880_volume_init_verbs,
2926 alc880_pin_6stack_init_verbs },
2927 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2928 .dac_nids = alc880_6st_dac_nids,
2929 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2930 .channel_mode = alc880_sixstack_modes,
2931 .input_mux = &alc880_6stack_capture_source,
2933 [ALC880_6ST_DIG] = {
2934 .mixers = { alc880_six_stack_mixer },
2935 .init_verbs = { alc880_volume_init_verbs,
2936 alc880_pin_6stack_init_verbs },
2937 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2938 .dac_nids = alc880_6st_dac_nids,
2939 .dig_out_nid = ALC880_DIGOUT_NID,
2940 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2941 .channel_mode = alc880_sixstack_modes,
2942 .input_mux = &alc880_6stack_capture_source,
2945 .mixers = { alc880_w810_base_mixer },
2946 .init_verbs = { alc880_volume_init_verbs,
2947 alc880_pin_w810_init_verbs,
2948 alc880_gpio2_init_verbs },
2949 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2950 .dac_nids = alc880_w810_dac_nids,
2951 .dig_out_nid = ALC880_DIGOUT_NID,
2952 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2953 .channel_mode = alc880_w810_modes,
2954 .input_mux = &alc880_capture_source,
2957 .mixers = { alc880_z71v_mixer },
2958 .init_verbs = { alc880_volume_init_verbs,
2959 alc880_pin_z71v_init_verbs },
2960 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2961 .dac_nids = alc880_z71v_dac_nids,
2962 .dig_out_nid = ALC880_DIGOUT_NID,
2964 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2965 .channel_mode = alc880_2_jack_modes,
2966 .input_mux = &alc880_capture_source,
2969 .mixers = { alc880_f1734_mixer },
2970 .init_verbs = { alc880_volume_init_verbs,
2971 alc880_pin_f1734_init_verbs },
2972 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2973 .dac_nids = alc880_f1734_dac_nids,
2975 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2976 .channel_mode = alc880_2_jack_modes,
2977 .input_mux = &alc880_capture_source,
2980 .mixers = { alc880_asus_mixer },
2981 .init_verbs = { alc880_volume_init_verbs,
2982 alc880_pin_asus_init_verbs,
2983 alc880_gpio1_init_verbs },
2984 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2985 .dac_nids = alc880_asus_dac_nids,
2986 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2987 .channel_mode = alc880_asus_modes,
2989 .input_mux = &alc880_capture_source,
2991 [ALC880_ASUS_DIG] = {
2992 .mixers = { alc880_asus_mixer },
2993 .init_verbs = { alc880_volume_init_verbs,
2994 alc880_pin_asus_init_verbs,
2995 alc880_gpio1_init_verbs },
2996 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2997 .dac_nids = alc880_asus_dac_nids,
2998 .dig_out_nid = ALC880_DIGOUT_NID,
2999 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3000 .channel_mode = alc880_asus_modes,
3002 .input_mux = &alc880_capture_source,
3004 [ALC880_ASUS_DIG2] = {
3005 .mixers = { alc880_asus_mixer },
3006 .init_verbs = { alc880_volume_init_verbs,
3007 alc880_pin_asus_init_verbs,
3008 alc880_gpio2_init_verbs }, /* use GPIO2 */
3009 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3010 .dac_nids = alc880_asus_dac_nids,
3011 .dig_out_nid = ALC880_DIGOUT_NID,
3012 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3013 .channel_mode = alc880_asus_modes,
3015 .input_mux = &alc880_capture_source,
3017 [ALC880_ASUS_W1V] = {
3018 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3019 .init_verbs = { alc880_volume_init_verbs,
3020 alc880_pin_asus_init_verbs,
3021 alc880_gpio1_init_verbs },
3022 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3023 .dac_nids = alc880_asus_dac_nids,
3024 .dig_out_nid = ALC880_DIGOUT_NID,
3025 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3026 .channel_mode = alc880_asus_modes,
3028 .input_mux = &alc880_capture_source,
3030 [ALC880_UNIWILL_DIG] = {
3031 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3032 .init_verbs = { alc880_volume_init_verbs,
3033 alc880_pin_asus_init_verbs },
3034 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3035 .dac_nids = alc880_asus_dac_nids,
3036 .dig_out_nid = ALC880_DIGOUT_NID,
3037 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3038 .channel_mode = alc880_asus_modes,
3040 .input_mux = &alc880_capture_source,
3042 [ALC880_UNIWILL] = {
3043 .mixers = { alc880_uniwill_mixer },
3044 .init_verbs = { alc880_volume_init_verbs,
3045 alc880_uniwill_init_verbs },
3046 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3047 .dac_nids = alc880_asus_dac_nids,
3048 .dig_out_nid = ALC880_DIGOUT_NID,
3049 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3050 .channel_mode = alc880_threestack_modes,
3052 .input_mux = &alc880_capture_source,
3053 .unsol_event = alc880_uniwill_unsol_event,
3054 .init_hook = alc880_uniwill_automute,
3056 [ALC880_UNIWILL_P53] = {
3057 .mixers = { alc880_uniwill_p53_mixer },
3058 .init_verbs = { alc880_volume_init_verbs,
3059 alc880_uniwill_p53_init_verbs },
3060 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3061 .dac_nids = alc880_asus_dac_nids,
3062 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3063 .channel_mode = alc880_threestack_modes,
3064 .input_mux = &alc880_capture_source,
3065 .unsol_event = alc880_uniwill_p53_unsol_event,
3066 .init_hook = alc880_uniwill_p53_hp_automute,
3068 [ALC880_FUJITSU] = {
3069 .mixers = { alc880_fujitsu_mixer,
3070 alc880_pcbeep_mixer, },
3071 .init_verbs = { alc880_volume_init_verbs,
3072 alc880_uniwill_p53_init_verbs,
3073 alc880_beep_init_verbs },
3074 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3075 .dac_nids = alc880_dac_nids,
3076 .dig_out_nid = ALC880_DIGOUT_NID,
3077 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3078 .channel_mode = alc880_2_jack_modes,
3079 .input_mux = &alc880_capture_source,
3080 .unsol_event = alc880_uniwill_p53_unsol_event,
3081 .init_hook = alc880_uniwill_p53_hp_automute,
3084 .mixers = { alc880_three_stack_mixer },
3085 .init_verbs = { alc880_volume_init_verbs,
3086 alc880_pin_clevo_init_verbs },
3087 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3088 .dac_nids = alc880_dac_nids,
3090 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3091 .channel_mode = alc880_threestack_modes,
3093 .input_mux = &alc880_capture_source,
3096 .mixers = { alc880_lg_mixer },
3097 .init_verbs = { alc880_volume_init_verbs,
3098 alc880_lg_init_verbs },
3099 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3100 .dac_nids = alc880_lg_dac_nids,
3101 .dig_out_nid = ALC880_DIGOUT_NID,
3102 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3103 .channel_mode = alc880_lg_ch_modes,
3105 .input_mux = &alc880_lg_capture_source,
3106 .unsol_event = alc880_lg_unsol_event,
3107 .init_hook = alc880_lg_automute,
3108 #ifdef CONFIG_SND_HDA_POWER_SAVE
3109 .loopbacks = alc880_lg_loopbacks,
3113 .mixers = { alc880_lg_lw_mixer },
3114 .init_verbs = { alc880_volume_init_verbs,
3115 alc880_lg_lw_init_verbs },
3116 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3117 .dac_nids = alc880_dac_nids,
3118 .dig_out_nid = ALC880_DIGOUT_NID,
3119 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3120 .channel_mode = alc880_lg_lw_modes,
3121 .input_mux = &alc880_lg_lw_capture_source,
3122 .unsol_event = alc880_lg_lw_unsol_event,
3123 .init_hook = alc880_lg_lw_automute,
3125 #ifdef CONFIG_SND_DEBUG
3127 .mixers = { alc880_test_mixer },
3128 .init_verbs = { alc880_test_init_verbs },
3129 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3130 .dac_nids = alc880_test_dac_nids,
3131 .dig_out_nid = ALC880_DIGOUT_NID,
3132 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3133 .channel_mode = alc880_test_modes,
3134 .input_mux = &alc880_test_capture_source,
3140 * Automatic parse of I/O pins from the BIOS configuration
3143 #define NUM_CONTROL_ALLOC 32
3144 #define NUM_VERB_ALLOC 32
3148 ALC_CTL_WIDGET_MUTE,
3151 static struct snd_kcontrol_new alc880_control_templates[] = {
3152 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3153 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3154 HDA_BIND_MUTE(NULL, 0, 0, 0),
3157 /* add dynamic controls */
3158 static int add_control(struct alc_spec *spec, int type, const char *name,
3161 struct snd_kcontrol_new *knew;
3163 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3164 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3166 /* array + terminator */
3167 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3170 if (spec->kctl_alloc) {
3171 memcpy(knew, spec->kctl_alloc,
3172 sizeof(*knew) * spec->num_kctl_alloc);
3173 kfree(spec->kctl_alloc);
3175 spec->kctl_alloc = knew;
3176 spec->num_kctl_alloc = num;
3179 knew = &spec->kctl_alloc[spec->num_kctl_used];
3180 *knew = alc880_control_templates[type];
3181 knew->name = kstrdup(name, GFP_KERNEL);
3184 knew->private_value = val;
3185 spec->num_kctl_used++;
3189 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3190 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3191 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3192 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3193 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3194 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3195 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3196 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3197 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3198 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3199 #define ALC880_PIN_CD_NID 0x1c
3201 /* fill in the dac_nids table from the parsed pin configuration */
3202 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3203 const struct auto_pin_cfg *cfg)
3209 memset(assigned, 0, sizeof(assigned));
3210 spec->multiout.dac_nids = spec->private_dac_nids;
3212 /* check the pins hardwired to audio widget */
3213 for (i = 0; i < cfg->line_outs; i++) {
3214 nid = cfg->line_out_pins[i];
3215 if (alc880_is_fixed_pin(nid)) {
3216 int idx = alc880_fixed_pin_idx(nid);
3217 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3221 /* left pins can be connect to any audio widget */
3222 for (i = 0; i < cfg->line_outs; i++) {
3223 nid = cfg->line_out_pins[i];
3224 if (alc880_is_fixed_pin(nid))
3226 /* search for an empty channel */
3227 for (j = 0; j < cfg->line_outs; j++) {
3229 spec->multiout.dac_nids[i] =
3230 alc880_idx_to_dac(j);
3236 spec->multiout.num_dacs = cfg->line_outs;
3240 /* add playback controls from the parsed DAC table */
3241 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3242 const struct auto_pin_cfg *cfg)
3245 static const char *chname[4] = {
3246 "Front", "Surround", NULL /*CLFE*/, "Side"
3251 for (i = 0; i < cfg->line_outs; i++) {
3252 if (!spec->multiout.dac_nids[i])
3254 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3257 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3258 "Center Playback Volume",
3259 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3263 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3264 "LFE Playback Volume",
3265 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3269 err = add_control(spec, ALC_CTL_BIND_MUTE,
3270 "Center Playback Switch",
3271 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3275 err = add_control(spec, ALC_CTL_BIND_MUTE,
3276 "LFE Playback Switch",
3277 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3282 sprintf(name, "%s Playback Volume", chname[i]);
3283 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3284 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3288 sprintf(name, "%s Playback Switch", chname[i]);
3289 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3290 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3299 /* add playback controls for speaker and HP outputs */
3300 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3310 if (alc880_is_fixed_pin(pin)) {
3311 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3312 /* specify the DAC as the extra output */
3313 if (!spec->multiout.hp_nid)
3314 spec->multiout.hp_nid = nid;
3316 spec->multiout.extra_out_nid[0] = nid;
3317 /* control HP volume/switch on the output mixer amp */
3318 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3319 sprintf(name, "%s Playback Volume", pfx);
3320 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3321 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3324 sprintf(name, "%s Playback Switch", pfx);
3325 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3326 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3329 } else if (alc880_is_multi_pin(pin)) {
3330 /* set manual connection */
3331 /* we have only a switch on HP-out PIN */
3332 sprintf(name, "%s Playback Switch", pfx);
3333 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3334 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3341 /* create input playback/capture controls for the given pin */
3342 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3343 const char *ctlname,
3344 int idx, hda_nid_t mix_nid)
3349 sprintf(name, "%s Playback Volume", ctlname);
3350 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3351 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3354 sprintf(name, "%s Playback Switch", ctlname);
3355 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3356 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3362 /* create playback/capture controls for input pins */
3363 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3364 const struct auto_pin_cfg *cfg)
3366 struct hda_input_mux *imux = &spec->private_imux;
3369 for (i = 0; i < AUTO_PIN_LAST; i++) {
3370 if (alc880_is_input_pin(cfg->input_pins[i])) {
3371 idx = alc880_input_pin_idx(cfg->input_pins[i]);
3372 err = new_analog_input(spec, cfg->input_pins[i],
3373 auto_pin_cfg_labels[i],
3377 imux->items[imux->num_items].label =
3378 auto_pin_cfg_labels[i];
3379 imux->items[imux->num_items].index =
3380 alc880_input_pin_idx(cfg->input_pins[i]);
3387 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3388 hda_nid_t nid, int pin_type,
3392 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3394 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3396 /* need the manual connection? */
3397 if (alc880_is_multi_pin(nid)) {
3398 struct alc_spec *spec = codec->spec;
3399 int idx = alc880_multi_pin_idx(nid);
3400 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3401 AC_VERB_SET_CONNECT_SEL,
3402 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3406 static int get_pin_type(int line_out_type)
3408 if (line_out_type == AUTO_PIN_HP_OUT)
3414 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3416 struct alc_spec *spec = codec->spec;
3419 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3420 for (i = 0; i < spec->autocfg.line_outs; i++) {
3421 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3422 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3423 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3427 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3429 struct alc_spec *spec = codec->spec;
3432 pin = spec->autocfg.speaker_pins[0];
3433 if (pin) /* connect to front */
3434 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3435 pin = spec->autocfg.hp_pins[0];
3436 if (pin) /* connect to front */
3437 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3440 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3442 struct alc_spec *spec = codec->spec;
3445 for (i = 0; i < AUTO_PIN_LAST; i++) {
3446 hda_nid_t nid = spec->autocfg.input_pins[i];
3447 if (alc880_is_input_pin(nid)) {
3448 snd_hda_codec_write(codec, nid, 0,
3449 AC_VERB_SET_PIN_WIDGET_CONTROL,
3450 i <= AUTO_PIN_FRONT_MIC ?
3451 PIN_VREF80 : PIN_IN);
3452 if (nid != ALC880_PIN_CD_NID)
3453 snd_hda_codec_write(codec, nid, 0,
3454 AC_VERB_SET_AMP_GAIN_MUTE,
3460 /* parse the BIOS configuration and set up the alc_spec */
3461 /* return 1 if successful, 0 if the proper config is not found,
3462 * or a negative error code
3464 static int alc880_parse_auto_config(struct hda_codec *codec)
3466 struct alc_spec *spec = codec->spec;
3468 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3470 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3474 if (!spec->autocfg.line_outs)
3475 return 0; /* can't find valid BIOS pin config */
3477 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3480 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3483 err = alc880_auto_create_extra_out(spec,
3484 spec->autocfg.speaker_pins[0],
3488 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3492 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3496 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3498 if (spec->autocfg.dig_out_pin)
3499 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3500 if (spec->autocfg.dig_in_pin)
3501 spec->dig_in_nid = ALC880_DIGIN_NID;
3503 if (spec->kctl_alloc)
3504 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3506 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3508 spec->num_mux_defs = 1;
3509 spec->input_mux = &spec->private_imux;
3514 /* additional initialization for auto-configuration model */
3515 static void alc880_auto_init(struct hda_codec *codec)
3517 alc880_auto_init_multi_out(codec);
3518 alc880_auto_init_extra_out(codec);
3519 alc880_auto_init_analog_input(codec);
3523 * OK, here we have finally the patch for ALC880
3526 static int patch_alc880(struct hda_codec *codec)
3528 struct alc_spec *spec;
3532 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3538 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3541 if (board_config < 0) {
3542 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3543 "trying auto-probe from BIOS...\n");
3544 board_config = ALC880_AUTO;
3547 if (board_config == ALC880_AUTO) {
3548 /* automatic parse from the BIOS config */
3549 err = alc880_parse_auto_config(codec);
3555 "hda_codec: Cannot set up configuration "
3556 "from BIOS. Using 3-stack mode...\n");
3557 board_config = ALC880_3ST;
3561 if (board_config != ALC880_AUTO)
3562 setup_preset(spec, &alc880_presets[board_config]);
3564 spec->stream_name_analog = "ALC880 Analog";
3565 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3566 spec->stream_analog_capture = &alc880_pcm_analog_capture;
3568 spec->stream_name_digital = "ALC880 Digital";
3569 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3570 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3572 if (!spec->adc_nids && spec->input_mux) {
3573 /* check whether NID 0x07 is valid */
3574 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3576 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3577 if (wcap != AC_WID_AUD_IN) {
3578 spec->adc_nids = alc880_adc_nids_alt;
3579 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3580 spec->mixers[spec->num_mixers] =
3581 alc880_capture_alt_mixer;
3584 spec->adc_nids = alc880_adc_nids;
3585 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3586 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3591 codec->patch_ops = alc_patch_ops;
3592 if (board_config == ALC880_AUTO)
3593 spec->init_hook = alc880_auto_init;
3594 #ifdef CONFIG_SND_HDA_POWER_SAVE
3595 if (!spec->loopback.amplist)
3596 spec->loopback.amplist = alc880_loopbacks;
3607 static hda_nid_t alc260_dac_nids[1] = {
3612 static hda_nid_t alc260_adc_nids[1] = {
3617 static hda_nid_t alc260_adc_nids_alt[1] = {
3622 static hda_nid_t alc260_hp_adc_nids[2] = {
3627 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
3628 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3630 static hda_nid_t alc260_dual_adc_nids[2] = {
3635 #define ALC260_DIGOUT_NID 0x03
3636 #define ALC260_DIGIN_NID 0x06
3638 static struct hda_input_mux alc260_capture_source = {
3642 { "Front Mic", 0x1 },
3648 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3649 * headphone jack and the internal CD lines since these are the only pins at
3650 * which audio can appear. For flexibility, also allow the option of
3651 * recording the mixer output on the second ADC (ADC0 doesn't have a
3652 * connection to the mixer output).
3654 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3658 { "Mic/Line", 0x0 },
3660 { "Headphone", 0x2 },
3666 { "Mic/Line", 0x0 },
3668 { "Headphone", 0x2 },
3675 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3676 * the Fujitsu S702x, but jacks are marked differently.
3678 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3685 { "Headphone", 0x5 },
3694 { "Headphone", 0x6 },
3700 * This is just place-holder, so there's something for alc_build_pcms to look
3701 * at when it calculates the maximum number of channels. ALC260 has no mixer
3702 * element which allows changing the channel mode, so the verb list is
3705 static struct hda_channel_mode alc260_modes[1] = {
3710 /* Mixer combinations
3712 * basic: base_output + input + pc_beep + capture
3713 * HP: base_output + input + capture_alt
3714 * HP_3013: hp_3013 + input + capture
3715 * fujitsu: fujitsu + capture
3716 * acer: acer + capture
3719 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3720 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3721 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3722 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3723 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3724 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3725 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3729 static struct snd_kcontrol_new alc260_input_mixer[] = {
3730 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3731 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3732 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3733 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3734 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3735 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3736 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3737 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3741 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3742 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3743 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3747 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3748 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3749 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3750 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3751 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3752 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3753 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3754 HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3755 HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3759 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
3760 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
3762 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3763 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3764 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3765 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3766 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3767 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3768 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3769 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3770 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3771 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3772 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3773 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3774 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3778 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
3779 * versions of the ALC260 don't act on requests to enable mic bias from NID
3780 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
3781 * datasheet doesn't mention this restriction. At this stage it's not clear
3782 * whether this behaviour is intentional or is a hardware bug in chip
3783 * revisions available in early 2006. Therefore for now allow the
3784 * "Headphone Jack Mode" control to span all choices, but if it turns out
3785 * that the lack of mic bias for this NID is intentional we could change the
3786 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3788 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3789 * don't appear to make the mic bias available from the "line" jack, even
3790 * though the NID used for this jack (0x14) can supply it. The theory is
3791 * that perhaps Acer have included blocking capacitors between the ALC260
3792 * and the output jack. If this turns out to be the case for all such
3793 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3794 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3796 * The C20x Tablet series have a mono internal speaker which is controlled
3797 * via the chip's Mono sum widget and pin complex, so include the necessary
3798 * controls for such models. On models without a "mono speaker" the control
3799 * won't do anything.
3801 static struct snd_kcontrol_new alc260_acer_mixer[] = {
3802 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3803 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3804 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3805 HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3807 HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3809 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3810 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3811 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3812 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3813 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3814 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3815 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3816 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3817 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3818 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3822 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3823 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
3825 static struct snd_kcontrol_new alc260_will_mixer[] = {
3826 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3827 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3828 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3829 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3830 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3831 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3832 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3833 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3834 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3835 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3836 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3837 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3841 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3842 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3844 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3845 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3846 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3847 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3848 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3849 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3850 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3851 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3852 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3853 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3854 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3858 /* capture mixer elements */
3859 static struct snd_kcontrol_new alc260_capture_mixer[] = {
3860 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3861 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3862 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3863 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3865 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3866 /* The multiple "Capture Source" controls confuse alsamixer
3867 * So call somewhat different..
3868 * FIXME: the controls appear in the "playback" view!
3870 /* .name = "Capture Source", */
3871 .name = "Input Source",
3873 .info = alc_mux_enum_info,
3874 .get = alc_mux_enum_get,
3875 .put = alc_mux_enum_put,
3880 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3881 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3882 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3885 /* The multiple "Capture Source" controls confuse alsamixer
3886 * So call somewhat different..
3887 * FIXME: the controls appear in the "playback" view!
3889 /* .name = "Capture Source", */
3890 .name = "Input Source",
3892 .info = alc_mux_enum_info,
3893 .get = alc_mux_enum_get,
3894 .put = alc_mux_enum_put,
3900 * initialization verbs
3902 static struct hda_verb alc260_init_verbs[] = {
3903 /* Line In pin widget for input */
3904 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3905 /* CD pin widget for input */
3906 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3907 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3908 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3909 /* Mic2 (front panel) pin widget for input and vref at 80% */
3910 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3911 /* LINE-2 is used for line-out in rear */
3912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3913 /* select line-out */
3914 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3916 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3918 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3920 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3921 /* mute capture amp left and right */
3922 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3923 /* set connection select to line in (default select for this ADC) */
3924 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3925 /* mute capture amp left and right */
3926 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3927 /* set connection select to line in (default select for this ADC) */
3928 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3929 /* set vol=0 Line-Out mixer amp left and right */
3930 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3931 /* unmute pin widget amp left and right (no gain on this amp) */
3932 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3933 /* set vol=0 HP mixer amp left and right */
3934 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3935 /* unmute pin widget amp left and right (no gain on this amp) */
3936 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3937 /* set vol=0 Mono mixer amp left and right */
3938 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3939 /* unmute pin widget amp left and right (no gain on this amp) */
3940 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3941 /* unmute LINE-2 out pin */
3942 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3943 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3946 /* mute analog inputs */
3947 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3948 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3949 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3950 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3951 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3952 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3953 /* mute Front out path */
3954 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3955 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3956 /* mute Headphone out path */
3957 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3958 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3959 /* mute Mono out path */
3960 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3961 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3965 #if 0 /* should be identical with alc260_init_verbs? */
3966 static struct hda_verb alc260_hp_init_verbs[] = {
3967 /* Headphone and output */
3968 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3970 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3971 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3972 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3973 /* Mic2 (front panel) pin widget for input and vref at 80% */
3974 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3975 /* Line In pin widget for input */
3976 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3977 /* Line-2 pin widget for output */
3978 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3979 /* CD pin widget for input */
3980 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3981 /* unmute amp left and right */
3982 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3983 /* set connection select to line in (default select for this ADC) */
3984 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3985 /* unmute Line-Out mixer amp left and right (volume = 0) */
3986 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3987 /* mute pin widget amp left and right (no gain on this amp) */
3988 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3989 /* unmute HP mixer amp left and right (volume = 0) */
3990 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3991 /* mute pin widget amp left and right (no gain on this amp) */
3992 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3993 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3996 /* mute analog inputs */
3997 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3998 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3999 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4000 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4001 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4002 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4003 /* Unmute Front out path */
4004 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4005 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4006 /* Unmute Headphone out path */
4007 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4008 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4009 /* Unmute Mono out path */
4010 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4011 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4016 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4017 /* Line out and output */
4018 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4020 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4021 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4022 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4023 /* Mic2 (front panel) pin widget for input and vref at 80% */
4024 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4025 /* Line In pin widget for input */
4026 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4027 /* Headphone pin widget for output */
4028 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4029 /* CD pin widget for input */
4030 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4031 /* unmute amp left and right */
4032 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4033 /* set connection select to line in (default select for this ADC) */
4034 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4035 /* unmute Line-Out mixer amp left and right (volume = 0) */
4036 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4037 /* mute pin widget amp left and right (no gain on this amp) */
4038 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4039 /* unmute HP mixer amp left and right (volume = 0) */
4040 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4041 /* mute pin widget amp left and right (no gain on this amp) */
4042 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4043 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4046 /* mute analog inputs */
4047 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4048 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4049 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4050 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4051 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4052 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4053 /* Unmute Front out path */
4054 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4055 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4056 /* Unmute Headphone out path */
4057 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4058 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4059 /* Unmute Mono out path */
4060 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4061 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4065 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4066 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4067 * audio = 0x16, internal speaker = 0x10.
4069 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4070 /* Disable all GPIOs */
4071 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4072 /* Internal speaker is connected to headphone pin */
4073 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4074 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4075 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4076 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4077 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4078 /* Ensure all other unused pins are disabled and muted. */
4079 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4080 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4081 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4082 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4083 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4084 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4085 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4086 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4088 /* Disable digital (SPDIF) pins */
4089 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4090 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4092 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4093 * when acting as an output.
4095 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4097 /* Start with output sum widgets muted and their output gains at min */
4098 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4099 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4100 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4101 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4102 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4103 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4104 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4105 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4106 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4108 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4109 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4110 /* Unmute Line1 pin widget output buffer since it starts as an output.
4111 * If the pin mode is changed by the user the pin mode control will
4112 * take care of enabling the pin's input/output buffers as needed.
4113 * Therefore there's no need to enable the input buffer at this
4116 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4117 /* Unmute input buffer of pin widget used for Line-in (no equiv
4120 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4122 /* Mute capture amp left and right */
4123 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4124 /* Set ADC connection select to match default mixer setting - line
4127 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4129 /* Do the same for the second ADC: mute capture input amp and
4130 * set ADC connection to line in (on mic1 pin)
4132 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4133 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4135 /* Mute all inputs to mixer widget (even unconnected ones) */
4136 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4137 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4138 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4139 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4140 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4141 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4142 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4143 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4148 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4149 * similar laptops (adapted from Fujitsu init verbs).
4151 static struct hda_verb alc260_acer_init_verbs[] = {
4152 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4153 * the headphone jack. Turn this on and rely on the standard mute
4154 * methods whenever the user wants to turn these outputs off.
4156 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4157 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4158 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4159 /* Internal speaker/Headphone jack is connected to Line-out pin */
4160 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4161 /* Internal microphone/Mic jack is connected to Mic1 pin */
4162 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4163 /* Line In jack is connected to Line1 pin */
4164 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4165 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4166 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4167 /* Ensure all other unused pins are disabled and muted. */
4168 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4169 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4170 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4171 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4172 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4173 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4174 /* Disable digital (SPDIF) pins */
4175 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4176 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4178 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4179 * bus when acting as outputs.
4181 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4182 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4184 /* Start with output sum widgets muted and their output gains at min */
4185 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4186 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4187 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4188 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4189 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4190 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4191 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4192 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4193 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4195 /* Unmute Line-out pin widget amp left and right
4196 * (no equiv mixer ctrl)
4198 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4199 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4200 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4201 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4202 * inputs. If the pin mode is changed by the user the pin mode control
4203 * will take care of enabling the pin's input/output buffers as needed.
4204 * Therefore there's no need to enable the input buffer at this
4207 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4208 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4210 /* Mute capture amp left and right */
4211 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4212 /* Set ADC connection select to match default mixer setting - mic
4215 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4217 /* Do similar with the second ADC: mute capture input amp and
4218 * set ADC connection to mic to match ALSA's default state.
4220 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4221 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4223 /* Mute all inputs to mixer widget (even unconnected ones) */
4224 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4225 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4226 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4229 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4230 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4231 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4236 static struct hda_verb alc260_will_verbs[] = {
4237 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4238 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4239 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4240 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4241 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4242 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4246 static struct hda_verb alc260_replacer_672v_verbs[] = {
4247 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4248 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4249 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4251 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4252 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4253 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4255 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4259 /* toggle speaker-output according to the hp-jack state */
4260 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4262 unsigned int present;
4264 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4265 present = snd_hda_codec_read(codec, 0x0f, 0,
4266 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4268 snd_hda_codec_write_cache(codec, 0x01, 0,
4269 AC_VERB_SET_GPIO_DATA, 1);
4270 snd_hda_codec_write_cache(codec, 0x0f, 0,
4271 AC_VERB_SET_PIN_WIDGET_CONTROL,
4274 snd_hda_codec_write_cache(codec, 0x01, 0,
4275 AC_VERB_SET_GPIO_DATA, 0);
4276 snd_hda_codec_write_cache(codec, 0x0f, 0,
4277 AC_VERB_SET_PIN_WIDGET_CONTROL,
4282 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4285 if ((res >> 26) == ALC880_HP_EVENT)
4286 alc260_replacer_672v_automute(codec);
4289 /* Test configuration for debugging, modelled after the ALC880 test
4292 #ifdef CONFIG_SND_DEBUG
4293 static hda_nid_t alc260_test_dac_nids[1] = {
4296 static hda_nid_t alc260_test_adc_nids[2] = {
4299 /* For testing the ALC260, each input MUX needs its own definition since
4300 * the signal assignments are different. This assumes that the first ADC
4303 static struct hda_input_mux alc260_test_capture_sources[2] = {
4307 { "MIC1 pin", 0x0 },
4308 { "MIC2 pin", 0x1 },
4309 { "LINE1 pin", 0x2 },
4310 { "LINE2 pin", 0x3 },
4312 { "LINE-OUT pin", 0x5 },
4313 { "HP-OUT pin", 0x6 },
4319 { "MIC1 pin", 0x0 },
4320 { "MIC2 pin", 0x1 },
4321 { "LINE1 pin", 0x2 },
4322 { "LINE2 pin", 0x3 },
4325 { "LINE-OUT pin", 0x6 },
4326 { "HP-OUT pin", 0x7 },
4330 static struct snd_kcontrol_new alc260_test_mixer[] = {
4331 /* Output driver widgets */
4332 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4333 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4334 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4335 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4336 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4337 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4339 /* Modes for retasking pin widgets
4340 * Note: the ALC260 doesn't seem to act on requests to enable mic
4341 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4342 * mention this restriction. At this stage it's not clear whether
4343 * this behaviour is intentional or is a hardware bug in chip
4344 * revisions available at least up until early 2006. Therefore for
4345 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4346 * choices, but if it turns out that the lack of mic bias for these
4347 * NIDs is intentional we could change their modes from
4348 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4350 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4351 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4352 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4353 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4354 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4355 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4357 /* Loopback mixer controls */
4358 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4359 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4360 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4361 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4362 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4363 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4364 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4365 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4366 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4367 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4368 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4369 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4370 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4371 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4372 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4373 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4375 /* Controls for GPIO pins, assuming they are configured as outputs */
4376 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4377 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4378 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4379 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4381 /* Switches to allow the digital IO pins to be enabled. The datasheet
4382 * is ambigious as to which NID is which; testing on laptops which
4383 * make this output available should provide clarification.
4385 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4386 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4388 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4389 * this output to turn on an external amplifier.
4391 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4392 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4396 static struct hda_verb alc260_test_init_verbs[] = {
4397 /* Enable all GPIOs as outputs with an initial value of 0 */
4398 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4399 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4400 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4402 /* Enable retasking pins as output, initially without power amp */
4403 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4404 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4405 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4406 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4407 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4408 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4410 /* Disable digital (SPDIF) pins initially, but users can enable
4411 * them via a mixer switch. In the case of SPDIF-out, this initverb
4412 * payload also sets the generation to 0, output to be in "consumer"
4413 * PCM format, copyright asserted, no pre-emphasis and no validity
4416 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4417 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4419 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4420 * OUT1 sum bus when acting as an output.
4422 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4423 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4424 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4425 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4427 /* Start with output sum widgets muted and their output gains at min */
4428 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4429 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4430 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4431 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4432 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4433 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4434 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4435 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4436 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4438 /* Unmute retasking pin widget output buffers since the default
4439 * state appears to be output. As the pin mode is changed by the
4440 * user the pin mode control will take care of enabling the pin's
4441 * input/output buffers as needed.
4443 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4444 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4445 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4446 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4447 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4448 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4449 /* Also unmute the mono-out pin widget */
4450 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4452 /* Mute capture amp left and right */
4453 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4454 /* Set ADC connection select to match default mixer setting (mic1
4457 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4459 /* Do the same for the second ADC: mute capture input amp and
4460 * set ADC connection to mic1 pin
4462 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4463 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4465 /* Mute all inputs to mixer widget (even unconnected ones) */
4466 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4467 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4468 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4469 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4470 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4471 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4472 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4473 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4479 static struct hda_pcm_stream alc260_pcm_analog_playback = {
4485 static struct hda_pcm_stream alc260_pcm_analog_capture = {
4491 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
4492 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
4495 * for BIOS auto-configuration
4498 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4502 unsigned long vol_val, sw_val;
4506 if (nid >= 0x0f && nid < 0x11) {
4507 nid_vol = nid - 0x7;
4508 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4509 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4510 } else if (nid == 0x11) {
4511 nid_vol = nid - 0x7;
4512 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4513 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4514 } else if (nid >= 0x12 && nid <= 0x15) {
4516 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4517 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4521 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4522 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4525 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4526 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4532 /* add playback controls from the parsed DAC table */
4533 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4534 const struct auto_pin_cfg *cfg)
4539 spec->multiout.num_dacs = 1;
4540 spec->multiout.dac_nids = spec->private_dac_nids;
4541 spec->multiout.dac_nids[0] = 0x02;
4543 nid = cfg->line_out_pins[0];
4545 err = alc260_add_playback_controls(spec, nid, "Front");
4550 nid = cfg->speaker_pins[0];
4552 err = alc260_add_playback_controls(spec, nid, "Speaker");
4557 nid = cfg->hp_pins[0];
4559 err = alc260_add_playback_controls(spec, nid, "Headphone");
4566 /* create playback/capture controls for input pins */
4567 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4568 const struct auto_pin_cfg *cfg)
4570 struct hda_input_mux *imux = &spec->private_imux;
4573 for (i = 0; i < AUTO_PIN_LAST; i++) {
4574 if (cfg->input_pins[i] >= 0x12) {
4575 idx = cfg->input_pins[i] - 0x12;
4576 err = new_analog_input(spec, cfg->input_pins[i],
4577 auto_pin_cfg_labels[i], idx,
4581 imux->items[imux->num_items].label =
4582 auto_pin_cfg_labels[i];
4583 imux->items[imux->num_items].index = idx;
4586 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4587 idx = cfg->input_pins[i] - 0x09;
4588 err = new_analog_input(spec, cfg->input_pins[i],
4589 auto_pin_cfg_labels[i], idx,
4593 imux->items[imux->num_items].label =
4594 auto_pin_cfg_labels[i];
4595 imux->items[imux->num_items].index = idx;
4602 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4603 hda_nid_t nid, int pin_type,
4607 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4609 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4611 /* need the manual connection? */
4613 int idx = nid - 0x12;
4614 snd_hda_codec_write(codec, idx + 0x0b, 0,
4615 AC_VERB_SET_CONNECT_SEL, sel_idx);
4619 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4621 struct alc_spec *spec = codec->spec;
4624 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4625 nid = spec->autocfg.line_out_pins[0];
4627 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4628 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4631 nid = spec->autocfg.speaker_pins[0];
4633 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4635 nid = spec->autocfg.hp_pins[0];
4637 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4640 #define ALC260_PIN_CD_NID 0x16
4641 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4643 struct alc_spec *spec = codec->spec;
4646 for (i = 0; i < AUTO_PIN_LAST; i++) {
4647 hda_nid_t nid = spec->autocfg.input_pins[i];
4649 snd_hda_codec_write(codec, nid, 0,
4650 AC_VERB_SET_PIN_WIDGET_CONTROL,
4651 i <= AUTO_PIN_FRONT_MIC ?
4652 PIN_VREF80 : PIN_IN);
4653 if (nid != ALC260_PIN_CD_NID)
4654 snd_hda_codec_write(codec, nid, 0,
4655 AC_VERB_SET_AMP_GAIN_MUTE,
4662 * generic initialization of ADC, input mixers and output mixers
4664 static struct hda_verb alc260_volume_init_verbs[] = {
4666 * Unmute ADC0-1 and set the default input to mic-in
4668 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4669 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4670 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4671 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4673 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4675 * Note: PASD motherboards uses the Line In 2 as the input for
4676 * front panel mic (mic 2)
4678 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4679 /* mute analog inputs */
4680 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4682 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4687 * Set up output mixers (0x08 - 0x0a)
4689 /* set vol=0 to output mixers */
4690 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4691 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4692 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4693 /* set up input amps for analog loopback */
4694 /* Amp Indices: DAC = 0, mixer = 1 */
4695 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4696 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4697 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4698 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4699 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4700 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4705 static int alc260_parse_auto_config(struct hda_codec *codec)
4707 struct alc_spec *spec = codec->spec;
4710 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4712 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4716 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4719 if (!spec->kctl_alloc)
4720 return 0; /* can't find valid BIOS pin config */
4721 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4725 spec->multiout.max_channels = 2;
4727 if (spec->autocfg.dig_out_pin)
4728 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4729 if (spec->kctl_alloc)
4730 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4732 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4734 spec->num_mux_defs = 1;
4735 spec->input_mux = &spec->private_imux;
4737 /* check whether NID 0x04 is valid */
4738 wcap = get_wcaps(codec, 0x04);
4739 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4740 if (wcap != AC_WID_AUD_IN) {
4741 spec->adc_nids = alc260_adc_nids_alt;
4742 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4743 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4745 spec->adc_nids = alc260_adc_nids;
4746 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4747 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4754 /* additional initialization for auto-configuration model */
4755 static void alc260_auto_init(struct hda_codec *codec)
4757 alc260_auto_init_multi_out(codec);
4758 alc260_auto_init_analog_input(codec);
4761 #ifdef CONFIG_SND_HDA_POWER_SAVE
4762 static struct hda_amp_list alc260_loopbacks[] = {
4763 { 0x07, HDA_INPUT, 0 },
4764 { 0x07, HDA_INPUT, 1 },
4765 { 0x07, HDA_INPUT, 2 },
4766 { 0x07, HDA_INPUT, 3 },
4767 { 0x07, HDA_INPUT, 4 },
4773 * ALC260 configurations
4775 static const char *alc260_models[ALC260_MODEL_LAST] = {
4776 [ALC260_BASIC] = "basic",
4778 [ALC260_HP_3013] = "hp-3013",
4779 [ALC260_FUJITSU_S702X] = "fujitsu",
4780 [ALC260_ACER] = "acer",
4781 [ALC260_WILL] = "will",
4782 [ALC260_REPLACER_672V] = "replacer",
4783 #ifdef CONFIG_SND_DEBUG
4784 [ALC260_TEST] = "test",
4786 [ALC260_AUTO] = "auto",
4789 static struct snd_pci_quirk alc260_cfg_tbl[] = {
4790 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4791 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4792 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4793 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4794 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4795 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4796 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4797 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4798 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4799 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4800 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4801 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4802 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4803 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4804 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4805 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4806 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4807 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4811 static struct alc_config_preset alc260_presets[] = {
4813 .mixers = { alc260_base_output_mixer,
4815 alc260_pc_beep_mixer,
4816 alc260_capture_mixer },
4817 .init_verbs = { alc260_init_verbs },
4818 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4819 .dac_nids = alc260_dac_nids,
4820 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4821 .adc_nids = alc260_adc_nids,
4822 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4823 .channel_mode = alc260_modes,
4824 .input_mux = &alc260_capture_source,
4827 .mixers = { alc260_base_output_mixer,
4829 alc260_capture_alt_mixer },
4830 .init_verbs = { alc260_init_verbs },
4831 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4832 .dac_nids = alc260_dac_nids,
4833 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4834 .adc_nids = alc260_hp_adc_nids,
4835 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4836 .channel_mode = alc260_modes,
4837 .input_mux = &alc260_capture_source,
4839 [ALC260_HP_3013] = {
4840 .mixers = { alc260_hp_3013_mixer,
4842 alc260_capture_alt_mixer },
4843 .init_verbs = { alc260_hp_3013_init_verbs },
4844 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4845 .dac_nids = alc260_dac_nids,
4846 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4847 .adc_nids = alc260_hp_adc_nids,
4848 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4849 .channel_mode = alc260_modes,
4850 .input_mux = &alc260_capture_source,
4852 [ALC260_FUJITSU_S702X] = {
4853 .mixers = { alc260_fujitsu_mixer,
4854 alc260_capture_mixer },
4855 .init_verbs = { alc260_fujitsu_init_verbs },
4856 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4857 .dac_nids = alc260_dac_nids,
4858 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4859 .adc_nids = alc260_dual_adc_nids,
4860 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4861 .channel_mode = alc260_modes,
4862 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4863 .input_mux = alc260_fujitsu_capture_sources,
4866 .mixers = { alc260_acer_mixer,
4867 alc260_capture_mixer },
4868 .init_verbs = { alc260_acer_init_verbs },
4869 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4870 .dac_nids = alc260_dac_nids,
4871 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4872 .adc_nids = alc260_dual_adc_nids,
4873 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4874 .channel_mode = alc260_modes,
4875 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4876 .input_mux = alc260_acer_capture_sources,
4879 .mixers = { alc260_will_mixer,
4880 alc260_capture_mixer },
4881 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
4882 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4883 .dac_nids = alc260_dac_nids,
4884 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4885 .adc_nids = alc260_adc_nids,
4886 .dig_out_nid = ALC260_DIGOUT_NID,
4887 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4888 .channel_mode = alc260_modes,
4889 .input_mux = &alc260_capture_source,
4891 [ALC260_REPLACER_672V] = {
4892 .mixers = { alc260_replacer_672v_mixer,
4893 alc260_capture_mixer },
4894 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4895 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4896 .dac_nids = alc260_dac_nids,
4897 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4898 .adc_nids = alc260_adc_nids,
4899 .dig_out_nid = ALC260_DIGOUT_NID,
4900 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4901 .channel_mode = alc260_modes,
4902 .input_mux = &alc260_capture_source,
4903 .unsol_event = alc260_replacer_672v_unsol_event,
4904 .init_hook = alc260_replacer_672v_automute,
4906 #ifdef CONFIG_SND_DEBUG
4908 .mixers = { alc260_test_mixer,
4909 alc260_capture_mixer },
4910 .init_verbs = { alc260_test_init_verbs },
4911 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4912 .dac_nids = alc260_test_dac_nids,
4913 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4914 .adc_nids = alc260_test_adc_nids,
4915 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4916 .channel_mode = alc260_modes,
4917 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4918 .input_mux = alc260_test_capture_sources,
4923 static int patch_alc260(struct hda_codec *codec)
4925 struct alc_spec *spec;
4926 int err, board_config;
4928 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4934 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4937 if (board_config < 0) {
4938 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4939 "trying auto-probe from BIOS...\n");
4940 board_config = ALC260_AUTO;
4943 if (board_config == ALC260_AUTO) {
4944 /* automatic parse from the BIOS config */
4945 err = alc260_parse_auto_config(codec);
4951 "hda_codec: Cannot set up configuration "
4952 "from BIOS. Using base mode...\n");
4953 board_config = ALC260_BASIC;
4957 if (board_config != ALC260_AUTO)
4958 setup_preset(spec, &alc260_presets[board_config]);
4960 spec->stream_name_analog = "ALC260 Analog";
4961 spec->stream_analog_playback = &alc260_pcm_analog_playback;
4962 spec->stream_analog_capture = &alc260_pcm_analog_capture;
4964 spec->stream_name_digital = "ALC260 Digital";
4965 spec->stream_digital_playback = &alc260_pcm_digital_playback;
4966 spec->stream_digital_capture = &alc260_pcm_digital_capture;
4968 codec->patch_ops = alc_patch_ops;
4969 if (board_config == ALC260_AUTO)
4970 spec->init_hook = alc260_auto_init;
4971 #ifdef CONFIG_SND_HDA_POWER_SAVE
4972 if (!spec->loopback.amplist)
4973 spec->loopback.amplist = alc260_loopbacks;
4983 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4984 * configuration. Each pin widget can choose any input DACs and a mixer.
4985 * Each ADC is connected from a mixer of all inputs. This makes possible
4986 * 6-channel independent captures.
4988 * In addition, an independent DAC for the multi-playback (not used in this
4991 #define ALC882_DIGOUT_NID 0x06
4992 #define ALC882_DIGIN_NID 0x0a
4994 static struct hda_channel_mode alc882_ch_modes[1] = {
4998 static hda_nid_t alc882_dac_nids[4] = {
4999 /* front, rear, clfe, rear_surr */
5000 0x02, 0x03, 0x04, 0x05
5003 /* identical with ALC880 */
5004 #define alc882_adc_nids alc880_adc_nids
5005 #define alc882_adc_nids_alt alc880_adc_nids_alt
5008 /* FIXME: should be a matrix-type input source selection */
5010 static struct hda_input_mux alc882_capture_source = {
5014 { "Front Mic", 0x1 },
5019 #define alc882_mux_enum_info alc_mux_enum_info
5020 #define alc882_mux_enum_get alc_mux_enum_get
5022 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5023 struct snd_ctl_elem_value *ucontrol)
5025 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5026 struct alc_spec *spec = codec->spec;
5027 const struct hda_input_mux *imux = spec->input_mux;
5028 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5029 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5030 hda_nid_t nid = capture_mixers[adc_idx];
5031 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5032 unsigned int i, idx;
5034 idx = ucontrol->value.enumerated.item[0];
5035 if (idx >= imux->num_items)
5036 idx = imux->num_items - 1;
5037 if (*cur_val == idx)
5039 for (i = 0; i < imux->num_items; i++) {
5040 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5041 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5042 imux->items[i].index,
5052 static struct hda_verb alc882_3ST_ch2_init[] = {
5053 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5054 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5055 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5056 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5063 static struct hda_verb alc882_3ST_ch6_init[] = {
5064 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5065 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5066 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5067 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5068 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5069 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5073 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5074 { 2, alc882_3ST_ch2_init },
5075 { 6, alc882_3ST_ch6_init },
5081 static struct hda_verb alc882_sixstack_ch6_init[] = {
5082 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5083 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5084 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5085 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5092 static struct hda_verb alc882_sixstack_ch8_init[] = {
5093 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5094 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5095 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5096 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5100 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5101 { 6, alc882_sixstack_ch6_init },
5102 { 8, alc882_sixstack_ch8_init },
5106 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5112 static struct hda_verb alc885_mbp_ch2_init[] = {
5113 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5114 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5115 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5122 static struct hda_verb alc885_mbp_ch6_init[] = {
5123 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5124 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5125 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5126 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5127 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5131 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5132 { 2, alc885_mbp_ch2_init },
5133 { 6, alc885_mbp_ch6_init },
5137 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5138 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5140 static struct snd_kcontrol_new alc882_base_mixer[] = {
5141 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5142 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5143 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5144 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5145 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5146 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5147 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5148 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5149 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5150 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5151 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5152 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5153 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5154 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5155 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5157 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5158 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5159 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5160 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5161 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5162 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5163 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5167 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5168 HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT),
5169 HDA_BIND_MUTE ("Master Switch", 0x0c, 0x02, HDA_INPUT),
5170 HDA_CODEC_MUTE ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT),
5171 HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT),
5172 HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT),
5173 HDA_CODEC_MUTE ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT),
5174 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5175 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5176 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT),
5177 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5180 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5181 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5182 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5183 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5184 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5185 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5186 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5187 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5188 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5189 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5190 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5191 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5195 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5196 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5197 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5198 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5199 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5200 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5201 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5202 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5203 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5204 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5205 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5206 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5207 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5208 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5212 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5213 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5215 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5216 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5217 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5218 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5219 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5220 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5221 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5222 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5223 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5224 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5225 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5226 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5227 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5228 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5232 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5233 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5234 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5235 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5236 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5237 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5238 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5239 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5240 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5241 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5242 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5243 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5244 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5248 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5250 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5251 .name = "Channel Mode",
5252 .info = alc_ch_mode_info,
5253 .get = alc_ch_mode_get,
5254 .put = alc_ch_mode_put,
5259 static struct hda_verb alc882_init_verbs[] = {
5260 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5261 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5262 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5265 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5266 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5267 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5269 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5270 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5271 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5273 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5274 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5275 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5277 /* Front Pin: output 0 (0x0c) */
5278 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5279 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5280 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5281 /* Rear Pin: output 1 (0x0d) */
5282 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5283 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5284 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5285 /* CLFE Pin: output 2 (0x0e) */
5286 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5287 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5288 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5289 /* Side Pin: output 3 (0x0f) */
5290 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5291 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5292 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5293 /* Mic (rear) pin: input vref at 80% */
5294 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5295 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5296 /* Front Mic pin: input vref at 80% */
5297 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5298 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5299 /* Line In pin: input */
5300 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5301 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5302 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5303 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5304 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5305 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5306 /* CD pin widget for input */
5307 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5309 /* FIXME: use matrix-type input source selection */
5310 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5311 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5312 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5313 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5314 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5315 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5317 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5318 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5319 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5320 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5322 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5323 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5325 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5326 /* ADC1: mute amp left and right */
5327 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5328 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5329 /* ADC2: mute amp left and right */
5330 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5331 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5332 /* ADC3: mute amp left and right */
5333 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5334 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5339 static struct hda_verb alc882_eapd_verbs[] = {
5340 /* change to EAPD mode */
5341 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5342 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5347 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5348 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5349 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5350 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5351 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5352 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5353 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5354 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5358 static struct hda_verb alc882_macpro_init_verbs[] = {
5359 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5361 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5362 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5363 /* Front Pin: output 0 (0x0c) */
5364 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5365 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5366 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5367 /* Front Mic pin: input vref at 80% */
5368 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5369 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5370 /* Speaker: output */
5371 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5372 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5373 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5374 /* Headphone output (output 0 - 0x0c) */
5375 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5376 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5377 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5379 /* FIXME: use matrix-type input source selection */
5380 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5381 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5382 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5383 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5384 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5385 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5387 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5388 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5389 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5390 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5392 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5393 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5394 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5395 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5396 /* ADC1: mute amp left and right */
5397 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5398 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5399 /* ADC2: mute amp left and right */
5400 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5401 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5402 /* ADC3: mute amp left and right */
5403 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5404 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5409 /* Macbook Pro rev3 */
5410 static struct hda_verb alc885_mbp3_init_verbs[] = {
5411 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5412 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5413 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5418 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5419 /* Front Pin: output 0 (0x0c) */
5420 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5421 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5422 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5423 /* HP Pin: output 0 (0x0d) */
5424 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5425 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5426 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5427 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5428 /* Mic (rear) pin: input vref at 80% */
5429 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5430 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5431 /* Front Mic pin: input vref at 80% */
5432 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5433 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5434 /* Line In pin: use output 1 when in LineOut mode */
5435 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5436 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5437 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5439 /* FIXME: use matrix-type input source selection */
5440 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5441 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5442 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5443 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5444 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5447 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5448 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5449 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5450 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5452 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5453 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5454 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5455 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5456 /* ADC1: mute amp left and right */
5457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5458 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5459 /* ADC2: mute amp left and right */
5460 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5461 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5462 /* ADC3: mute amp left and right */
5463 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5464 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5469 /* iMac 24 mixer. */
5470 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5471 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5472 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5476 /* iMac 24 init verbs. */
5477 static struct hda_verb alc885_imac24_init_verbs[] = {
5478 /* Internal speakers: output 0 (0x0c) */
5479 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5480 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5481 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5482 /* Internal speakers: output 0 (0x0c) */
5483 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5484 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5485 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5486 /* Headphone: output 0 (0x0c) */
5487 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5488 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5489 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5490 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5491 /* Front Mic: input vref at 80% */
5492 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5493 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5497 /* Toggle speaker-output according to the hp-jack state */
5498 static void alc885_imac24_automute(struct hda_codec *codec)
5500 unsigned int present;
5502 present = snd_hda_codec_read(codec, 0x14, 0,
5503 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5504 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5505 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5506 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5507 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5510 /* Processes unsolicited events. */
5511 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5514 /* Headphone insertion or removal. */
5515 if ((res >> 26) == ALC880_HP_EVENT)
5516 alc885_imac24_automute(codec);
5519 static void alc885_mbp3_automute(struct hda_codec *codec)
5521 unsigned int present;
5523 present = snd_hda_codec_read(codec, 0x15, 0,
5524 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5525 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
5526 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5527 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5528 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5531 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5534 /* Headphone insertion or removal. */
5535 if ((res >> 26) == ALC880_HP_EVENT)
5536 alc885_mbp3_automute(codec);
5540 static struct hda_verb alc882_targa_verbs[] = {
5541 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5542 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5544 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5545 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5547 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5548 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5549 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5551 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5552 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5553 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5554 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5558 /* toggle speaker-output according to the hp-jack state */
5559 static void alc882_targa_automute(struct hda_codec *codec)
5561 unsigned int present;
5563 present = snd_hda_codec_read(codec, 0x14, 0,
5564 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5565 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5566 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5567 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5571 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5573 /* Looks like the unsol event is incompatible with the standard
5574 * definition. 4bit tag is placed at 26 bit!
5576 if (((res >> 26) == ALC880_HP_EVENT)) {
5577 alc882_targa_automute(codec);
5581 static struct hda_verb alc882_asus_a7j_verbs[] = {
5582 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5583 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5585 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5586 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5587 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5589 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5590 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5591 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5593 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5594 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5595 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5599 static struct hda_verb alc882_asus_a7m_verbs[] = {
5600 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5601 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5604 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5605 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5607 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5608 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5609 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5611 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5612 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5613 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5617 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5619 unsigned int gpiostate, gpiomask, gpiodir;
5621 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5622 AC_VERB_GET_GPIO_DATA, 0);
5625 gpiostate |= (1 << pin);
5627 gpiostate &= ~(1 << pin);
5629 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5630 AC_VERB_GET_GPIO_MASK, 0);
5631 gpiomask |= (1 << pin);
5633 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5634 AC_VERB_GET_GPIO_DIRECTION, 0);
5635 gpiodir |= (1 << pin);
5638 snd_hda_codec_write(codec, codec->afg, 0,
5639 AC_VERB_SET_GPIO_MASK, gpiomask);
5640 snd_hda_codec_write(codec, codec->afg, 0,
5641 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5645 snd_hda_codec_write(codec, codec->afg, 0,
5646 AC_VERB_SET_GPIO_DATA, gpiostate);
5649 /* set up GPIO at initialization */
5650 static void alc885_macpro_init_hook(struct hda_codec *codec)
5652 alc882_gpio_mute(codec, 0, 0);
5653 alc882_gpio_mute(codec, 1, 0);
5656 /* set up GPIO and update auto-muting at initialization */
5657 static void alc885_imac24_init_hook(struct hda_codec *codec)
5659 alc885_macpro_init_hook(codec);
5660 alc885_imac24_automute(codec);
5664 * generic initialization of ADC, input mixers and output mixers
5666 static struct hda_verb alc882_auto_init_verbs[] = {
5668 * Unmute ADC0-2 and set the default input to mic-in
5670 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5671 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5672 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5673 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5674 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5675 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5677 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5679 * Note: PASD motherboards uses the Line In 2 as the input for
5680 * front panel mic (mic 2)
5682 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5683 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5684 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5685 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5690 * Set up output mixers (0x0c - 0x0f)
5692 /* set vol=0 to output mixers */
5693 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5694 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5695 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5696 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5697 /* set up input amps for analog loopback */
5698 /* Amp Indices: DAC = 0, mixer = 1 */
5699 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5700 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5701 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5702 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5703 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5704 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5705 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5706 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5707 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5708 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5710 /* FIXME: use matrix-type input source selection */
5711 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5712 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5713 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5714 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5715 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5716 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5718 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5719 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5720 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5721 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5723 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5724 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5725 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5726 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5731 /* capture mixer elements */
5732 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5733 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5734 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5735 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5736 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5739 /* The multiple "Capture Source" controls confuse alsamixer
5740 * So call somewhat different..
5741 * FIXME: the controls appear in the "playback" view!
5743 /* .name = "Capture Source", */
5744 .name = "Input Source",
5746 .info = alc882_mux_enum_info,
5747 .get = alc882_mux_enum_get,
5748 .put = alc882_mux_enum_put,
5753 static struct snd_kcontrol_new alc882_capture_mixer[] = {
5754 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5755 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5756 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5757 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5758 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5759 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5761 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5762 /* The multiple "Capture Source" controls confuse alsamixer
5763 * So call somewhat different..
5764 * FIXME: the controls appear in the "playback" view!
5766 /* .name = "Capture Source", */
5767 .name = "Input Source",
5769 .info = alc882_mux_enum_info,
5770 .get = alc882_mux_enum_get,
5771 .put = alc882_mux_enum_put,
5776 #ifdef CONFIG_SND_HDA_POWER_SAVE
5777 #define alc882_loopbacks alc880_loopbacks
5780 /* pcm configuration: identiacal with ALC880 */
5781 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
5782 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
5783 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
5784 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
5787 * configuration and preset
5789 static const char *alc882_models[ALC882_MODEL_LAST] = {
5790 [ALC882_3ST_DIG] = "3stack-dig",
5791 [ALC882_6ST_DIG] = "6stack-dig",
5792 [ALC882_ARIMA] = "arima",
5793 [ALC882_W2JC] = "w2jc",
5794 [ALC882_TARGA] = "targa",
5795 [ALC882_ASUS_A7J] = "asus-a7j",
5796 [ALC882_ASUS_A7M] = "asus-a7m",
5797 [ALC885_MACPRO] = "macpro",
5798 [ALC885_MBP3] = "mbp3",
5799 [ALC885_IMAC24] = "imac24",
5800 [ALC882_AUTO] = "auto",
5803 static struct snd_pci_quirk alc882_cfg_tbl[] = {
5804 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5805 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5806 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
5807 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
5808 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5809 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5810 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5811 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5812 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
5813 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5814 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5818 static struct alc_config_preset alc882_presets[] = {
5819 [ALC882_3ST_DIG] = {
5820 .mixers = { alc882_base_mixer },
5821 .init_verbs = { alc882_init_verbs },
5822 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5823 .dac_nids = alc882_dac_nids,
5824 .dig_out_nid = ALC882_DIGOUT_NID,
5825 .dig_in_nid = ALC882_DIGIN_NID,
5826 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5827 .channel_mode = alc882_ch_modes,
5829 .input_mux = &alc882_capture_source,
5831 [ALC882_6ST_DIG] = {
5832 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5833 .init_verbs = { alc882_init_verbs },
5834 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5835 .dac_nids = alc882_dac_nids,
5836 .dig_out_nid = ALC882_DIGOUT_NID,
5837 .dig_in_nid = ALC882_DIGIN_NID,
5838 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5839 .channel_mode = alc882_sixstack_modes,
5840 .input_mux = &alc882_capture_source,
5843 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5844 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5845 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5846 .dac_nids = alc882_dac_nids,
5847 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5848 .channel_mode = alc882_sixstack_modes,
5849 .input_mux = &alc882_capture_source,
5852 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5853 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5854 alc880_gpio1_init_verbs },
5855 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5856 .dac_nids = alc882_dac_nids,
5857 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5858 .channel_mode = alc880_threestack_modes,
5860 .input_mux = &alc882_capture_source,
5861 .dig_out_nid = ALC882_DIGOUT_NID,
5864 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
5865 .init_verbs = { alc885_mbp3_init_verbs,
5866 alc880_gpio1_init_verbs },
5867 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5868 .dac_nids = alc882_dac_nids,
5869 .channel_mode = alc885_mbp_6ch_modes,
5870 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
5871 .input_mux = &alc882_capture_source,
5872 .dig_out_nid = ALC882_DIGOUT_NID,
5873 .dig_in_nid = ALC882_DIGIN_NID,
5874 .unsol_event = alc885_mbp3_unsol_event,
5875 .init_hook = alc885_mbp3_automute,
5878 .mixers = { alc882_macpro_mixer },
5879 .init_verbs = { alc882_macpro_init_verbs },
5880 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5881 .dac_nids = alc882_dac_nids,
5882 .dig_out_nid = ALC882_DIGOUT_NID,
5883 .dig_in_nid = ALC882_DIGIN_NID,
5884 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5885 .channel_mode = alc882_ch_modes,
5886 .input_mux = &alc882_capture_source,
5887 .init_hook = alc885_macpro_init_hook,
5890 .mixers = { alc885_imac24_mixer },
5891 .init_verbs = { alc885_imac24_init_verbs },
5892 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5893 .dac_nids = alc882_dac_nids,
5894 .dig_out_nid = ALC882_DIGOUT_NID,
5895 .dig_in_nid = ALC882_DIGIN_NID,
5896 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5897 .channel_mode = alc882_ch_modes,
5898 .input_mux = &alc882_capture_source,
5899 .unsol_event = alc885_imac24_unsol_event,
5900 .init_hook = alc885_imac24_init_hook,
5903 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5904 alc882_capture_mixer },
5905 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5906 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5907 .dac_nids = alc882_dac_nids,
5908 .dig_out_nid = ALC882_DIGOUT_NID,
5909 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5910 .adc_nids = alc882_adc_nids,
5911 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5912 .channel_mode = alc882_3ST_6ch_modes,
5914 .input_mux = &alc882_capture_source,
5915 .unsol_event = alc882_targa_unsol_event,
5916 .init_hook = alc882_targa_automute,
5918 [ALC882_ASUS_A7J] = {
5919 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5920 alc882_capture_mixer },
5921 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5922 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5923 .dac_nids = alc882_dac_nids,
5924 .dig_out_nid = ALC882_DIGOUT_NID,
5925 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5926 .adc_nids = alc882_adc_nids,
5927 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5928 .channel_mode = alc882_3ST_6ch_modes,
5930 .input_mux = &alc882_capture_source,
5932 [ALC882_ASUS_A7M] = {
5933 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
5934 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5935 alc880_gpio1_init_verbs,
5936 alc882_asus_a7m_verbs },
5937 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5938 .dac_nids = alc882_dac_nids,
5939 .dig_out_nid = ALC882_DIGOUT_NID,
5940 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5941 .channel_mode = alc880_threestack_modes,
5943 .input_mux = &alc882_capture_source,
5952 PINFIX_ABIT_AW9D_MAX
5955 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5956 { 0x15, 0x01080104 }, /* side */
5957 { 0x16, 0x01011012 }, /* rear */
5958 { 0x17, 0x01016011 }, /* clfe */
5962 static const struct alc_pincfg *alc882_pin_fixes[] = {
5963 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5966 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5967 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5972 * BIOS auto configuration
5974 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5975 hda_nid_t nid, int pin_type,
5979 struct alc_spec *spec = codec->spec;
5982 if (spec->multiout.dac_nids[dac_idx] == 0x25)
5985 idx = spec->multiout.dac_nids[dac_idx] - 2;
5987 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5989 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5991 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5995 static void alc882_auto_init_multi_out(struct hda_codec *codec)
5997 struct alc_spec *spec = codec->spec;
6000 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6001 for (i = 0; i <= HDA_SIDE; i++) {
6002 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6003 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6005 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6010 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6012 struct alc_spec *spec = codec->spec;
6015 pin = spec->autocfg.hp_pins[0];
6016 if (pin) /* connect to front */
6018 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6021 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6022 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6024 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6026 struct alc_spec *spec = codec->spec;
6029 for (i = 0; i < AUTO_PIN_LAST; i++) {
6030 hda_nid_t nid = spec->autocfg.input_pins[i];
6031 if (alc882_is_input_pin(nid)) {
6032 snd_hda_codec_write(codec, nid, 0,
6033 AC_VERB_SET_PIN_WIDGET_CONTROL,
6034 i <= AUTO_PIN_FRONT_MIC ?
6035 PIN_VREF80 : PIN_IN);
6036 if (nid != ALC882_PIN_CD_NID)
6037 snd_hda_codec_write(codec, nid, 0,
6038 AC_VERB_SET_AMP_GAIN_MUTE,
6044 /* add mic boosts if needed */
6045 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6047 struct alc_spec *spec = codec->spec;
6051 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6053 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6055 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6059 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6061 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6063 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6070 /* almost identical with ALC880 parser... */
6071 static int alc882_parse_auto_config(struct hda_codec *codec)
6073 struct alc_spec *spec = codec->spec;
6074 int err = alc880_parse_auto_config(codec);
6079 return 0; /* no config found */
6081 err = alc_auto_add_mic_boost(codec);
6085 /* hack - override the init verbs */
6086 spec->init_verbs[0] = alc882_auto_init_verbs;
6088 return 1; /* config found */
6091 /* additional initialization for auto-configuration model */
6092 static void alc882_auto_init(struct hda_codec *codec)
6094 alc882_auto_init_multi_out(codec);
6095 alc882_auto_init_hp_out(codec);
6096 alc882_auto_init_analog_input(codec);
6099 static int patch_alc882(struct hda_codec *codec)
6101 struct alc_spec *spec;
6102 int err, board_config;
6104 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6110 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6114 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6115 /* Pick up systems that don't supply PCI SSID */
6116 switch (codec->subsystem_id) {
6117 case 0x106b0c00: /* Mac Pro */
6118 board_config = ALC885_MACPRO;
6120 case 0x106b1000: /* iMac 24 */
6121 board_config = ALC885_IMAC24;
6123 case 0x106b2c00: /* Macbook Pro rev3 */
6124 board_config = ALC885_MBP3;
6127 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6128 "trying auto-probe from BIOS...\n");
6129 board_config = ALC882_AUTO;
6133 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6135 if (board_config == ALC882_AUTO) {
6136 /* automatic parse from the BIOS config */
6137 err = alc882_parse_auto_config(codec);
6143 "hda_codec: Cannot set up configuration "
6144 "from BIOS. Using base mode...\n");
6145 board_config = ALC882_3ST_DIG;
6149 if (board_config != ALC882_AUTO)
6150 setup_preset(spec, &alc882_presets[board_config]);
6152 spec->stream_name_analog = "ALC882 Analog";
6153 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6154 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6156 spec->stream_name_digital = "ALC882 Digital";
6157 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6158 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6160 if (!spec->adc_nids && spec->input_mux) {
6161 /* check whether NID 0x07 is valid */
6162 unsigned int wcap = get_wcaps(codec, 0x07);
6164 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6165 if (wcap != AC_WID_AUD_IN) {
6166 spec->adc_nids = alc882_adc_nids_alt;
6167 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6168 spec->mixers[spec->num_mixers] =
6169 alc882_capture_alt_mixer;
6172 spec->adc_nids = alc882_adc_nids;
6173 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6174 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6179 codec->patch_ops = alc_patch_ops;
6180 if (board_config == ALC882_AUTO)
6181 spec->init_hook = alc882_auto_init;
6182 #ifdef CONFIG_SND_HDA_POWER_SAVE
6183 if (!spec->loopback.amplist)
6184 spec->loopback.amplist = alc882_loopbacks;
6193 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6194 * configuration. Each pin widget can choose any input DACs and a mixer.
6195 * Each ADC is connected from a mixer of all inputs. This makes possible
6196 * 6-channel independent captures.
6198 * In addition, an independent DAC for the multi-playback (not used in this
6201 #define ALC883_DIGOUT_NID 0x06
6202 #define ALC883_DIGIN_NID 0x0a
6204 static hda_nid_t alc883_dac_nids[4] = {
6205 /* front, rear, clfe, rear_surr */
6206 0x02, 0x04, 0x03, 0x05
6209 static hda_nid_t alc883_adc_nids[2] = {
6215 /* FIXME: should be a matrix-type input source selection */
6217 static struct hda_input_mux alc883_capture_source = {
6221 { "Front Mic", 0x1 },
6227 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6235 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6245 #define alc883_mux_enum_info alc_mux_enum_info
6246 #define alc883_mux_enum_get alc_mux_enum_get
6248 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
6249 struct snd_ctl_elem_value *ucontrol)
6251 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6252 struct alc_spec *spec = codec->spec;
6253 const struct hda_input_mux *imux = spec->input_mux;
6254 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
6255 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
6256 hda_nid_t nid = capture_mixers[adc_idx];
6257 unsigned int *cur_val = &spec->cur_mux[adc_idx];
6258 unsigned int i, idx;
6260 idx = ucontrol->value.enumerated.item[0];
6261 if (idx >= imux->num_items)
6262 idx = imux->num_items - 1;
6263 if (*cur_val == idx)
6265 for (i = 0; i < imux->num_items; i++) {
6266 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
6267 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
6268 imux->items[i].index,
6278 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6285 static struct hda_verb alc883_3ST_ch2_init[] = {
6286 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6287 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6288 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6289 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6296 static struct hda_verb alc883_3ST_ch4_init[] = {
6297 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6298 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6299 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6300 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6301 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6308 static struct hda_verb alc883_3ST_ch6_init[] = {
6309 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6310 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6311 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6312 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6313 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6314 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6318 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6319 { 2, alc883_3ST_ch2_init },
6320 { 4, alc883_3ST_ch4_init },
6321 { 6, alc883_3ST_ch6_init },
6327 static struct hda_verb alc883_sixstack_ch6_init[] = {
6328 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6329 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6330 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6331 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6338 static struct hda_verb alc883_sixstack_ch8_init[] = {
6339 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6340 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6341 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6342 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6346 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6347 { 6, alc883_sixstack_ch6_init },
6348 { 8, alc883_sixstack_ch8_init },
6351 static struct hda_verb alc883_medion_eapd_verbs[] = {
6352 /* eanable EAPD on medion laptop */
6353 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6354 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6358 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6359 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6362 static struct snd_kcontrol_new alc883_base_mixer[] = {
6363 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6364 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6365 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6366 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6367 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6368 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6369 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6370 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6371 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6372 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6373 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6374 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6375 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6376 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6377 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6378 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6379 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6380 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6381 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6382 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6383 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6384 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6385 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6386 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6387 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6388 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6389 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6391 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6392 /* .name = "Capture Source", */
6393 .name = "Input Source",
6395 .info = alc883_mux_enum_info,
6396 .get = alc883_mux_enum_get,
6397 .put = alc883_mux_enum_put,
6402 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6403 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6404 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6405 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6406 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6407 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6408 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6409 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6410 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6411 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6412 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6413 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6414 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6415 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6416 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6417 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6418 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6419 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6421 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6422 /* .name = "Capture Source", */
6423 .name = "Input Source",
6425 .info = alc883_mux_enum_info,
6426 .get = alc883_mux_enum_get,
6427 .put = alc883_mux_enum_put,
6432 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6433 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6434 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6435 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6436 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6437 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6438 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6439 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6440 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6441 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6442 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6443 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6444 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6445 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6446 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6447 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6448 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6449 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6450 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6451 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6453 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6454 /* .name = "Capture Source", */
6455 .name = "Input Source",
6457 .info = alc883_mux_enum_info,
6458 .get = alc883_mux_enum_get,
6459 .put = alc883_mux_enum_put,
6464 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6465 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6466 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6467 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6468 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6469 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6470 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6471 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6472 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6473 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6474 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6475 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6476 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6477 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6478 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6479 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6480 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6481 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6482 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6483 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6484 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6485 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6486 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6487 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6488 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6489 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6492 /* .name = "Capture Source", */
6493 .name = "Input Source",
6495 .info = alc883_mux_enum_info,
6496 .get = alc883_mux_enum_get,
6497 .put = alc883_mux_enum_put,
6502 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6503 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6504 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6505 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6506 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6507 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6508 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6509 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6510 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6511 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6512 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6513 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6514 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6515 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6516 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6517 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6518 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6519 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6520 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6521 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6522 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6523 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6524 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6525 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6528 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6529 /* .name = "Capture Source", */
6530 .name = "Input Source",
6532 .info = alc883_mux_enum_info,
6533 .get = alc883_mux_enum_get,
6534 .put = alc883_mux_enum_put,
6539 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6540 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6541 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6542 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6543 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6544 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6545 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6546 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6547 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6548 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6549 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6550 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6551 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6552 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6553 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6554 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6555 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6556 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6557 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6558 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6559 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6561 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6562 /* .name = "Capture Source", */
6563 .name = "Input Source",
6565 .info = alc883_mux_enum_info,
6566 .get = alc883_mux_enum_get,
6567 .put = alc883_mux_enum_put,
6572 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6573 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6574 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6575 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6576 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6577 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6579 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6580 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6581 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6582 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6583 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6584 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6586 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6587 /* .name = "Capture Source", */
6588 .name = "Input Source",
6590 .info = alc883_mux_enum_info,
6591 .get = alc883_mux_enum_get,
6592 .put = alc883_mux_enum_put,
6597 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6598 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6599 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6600 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6601 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6602 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6603 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6604 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6605 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6606 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6607 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6609 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6610 /* .name = "Capture Source", */
6611 .name = "Input Source",
6613 .info = alc883_mux_enum_info,
6614 .get = alc883_mux_enum_get,
6615 .put = alc883_mux_enum_put,
6620 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6621 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6622 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6623 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6624 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6625 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6626 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6627 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6628 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6629 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6630 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6631 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6632 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6633 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6635 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6636 /* .name = "Capture Source", */
6637 .name = "Input Source",
6639 .info = alc883_mux_enum_info,
6640 .get = alc883_mux_enum_get,
6641 .put = alc883_mux_enum_put,
6646 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6647 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6648 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6649 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6650 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6651 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6653 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6654 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6655 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6656 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6657 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6658 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6659 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6661 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6662 /* .name = "Capture Source", */
6663 .name = "Input Source",
6665 .info = alc883_mux_enum_info,
6666 .get = alc883_mux_enum_get,
6667 .put = alc883_mux_enum_put,
6672 static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6673 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6674 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6675 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6676 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6677 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6678 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6679 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6680 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6681 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6682 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6683 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6684 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6685 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6686 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6687 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6688 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6689 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6690 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6691 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6692 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6693 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6694 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6695 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6696 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6697 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6698 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6699 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6701 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6702 /* .name = "Capture Source", */
6703 .name = "Input Source",
6705 .info = alc883_mux_enum_info,
6706 .get = alc883_mux_enum_get,
6707 .put = alc883_mux_enum_put,
6712 static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6713 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6714 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6715 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6716 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6717 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6718 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6719 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6720 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6721 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6722 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6723 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6724 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6725 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6726 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6727 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6729 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6730 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6731 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6732 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6733 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6734 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6735 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6736 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6737 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 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_acer_aspire_mixer[] = {
6751 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6752 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6753 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6754 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6755 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6756 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6757 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6758 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6759 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6760 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6761 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6762 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6764 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6765 /* .name = "Capture Source", */
6766 .name = "Input Source",
6768 .info = alc883_mux_enum_info,
6769 .get = alc883_mux_enum_get,
6770 .put = alc883_mux_enum_put,
6775 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6778 .name = "Channel Mode",
6779 .info = alc_ch_mode_info,
6780 .get = alc_ch_mode_get,
6781 .put = alc_ch_mode_put,
6786 static struct hda_verb alc883_init_verbs[] = {
6787 /* ADC1: mute amp left and right */
6788 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6789 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6790 /* ADC2: mute amp left and right */
6791 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6792 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6793 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6794 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6795 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6796 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6798 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6799 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6800 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6802 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6803 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6804 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6806 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6807 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6808 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6810 /* mute analog input loopbacks */
6811 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6812 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6813 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6814 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6815 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6817 /* Front Pin: output 0 (0x0c) */
6818 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6819 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6820 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6821 /* Rear Pin: output 1 (0x0d) */
6822 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6823 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6824 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6825 /* CLFE Pin: output 2 (0x0e) */
6826 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6827 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6828 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6829 /* Side Pin: output 3 (0x0f) */
6830 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6831 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6832 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6833 /* Mic (rear) pin: input vref at 80% */
6834 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6835 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6836 /* Front Mic pin: input vref at 80% */
6837 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6838 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6839 /* Line In pin: input */
6840 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6841 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6842 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6843 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6844 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6845 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6846 /* CD pin widget for input */
6847 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6849 /* FIXME: use matrix-type input source selection */
6850 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6852 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6853 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6854 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6855 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6857 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6858 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6859 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6860 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6864 /* toggle speaker-output according to the hp-jack state */
6865 static void alc883_mitac_hp_automute(struct hda_codec *codec)
6867 unsigned int present;
6869 present = snd_hda_codec_read(codec, 0x15, 0,
6870 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6871 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6872 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6873 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
6874 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6877 /* auto-toggle front mic */
6879 static void alc883_mitac_mic_automute(struct hda_codec *codec)
6881 unsigned int present;
6884 present = snd_hda_codec_read(codec, 0x18, 0,
6885 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6886 bits = present ? HDA_AMP_MUTE : 0;
6887 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
6891 static void alc883_mitac_automute(struct hda_codec *codec)
6893 alc883_mitac_hp_automute(codec);
6894 /* alc883_mitac_mic_automute(codec); */
6897 static void alc883_mitac_unsol_event(struct hda_codec *codec,
6900 switch (res >> 26) {
6901 case ALC880_HP_EVENT:
6902 alc883_mitac_hp_automute(codec);
6904 case ALC880_MIC_EVENT:
6905 /* alc883_mitac_mic_automute(codec); */
6910 static struct hda_verb alc883_mitac_verbs[] = {
6912 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6913 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6915 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
6916 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6918 /* enable unsolicited event */
6919 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6920 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
6925 static struct hda_verb alc883_tagra_verbs[] = {
6926 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6927 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6929 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6930 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6932 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6933 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6934 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6936 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6937 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6938 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6939 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6944 static struct hda_verb alc883_lenovo_101e_verbs[] = {
6945 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6946 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6947 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6951 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6952 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6953 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6954 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6955 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6959 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6961 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6962 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6963 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6964 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6968 static struct hda_verb alc883_haier_w66_verbs[] = {
6969 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6970 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6972 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6974 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6975 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6976 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6977 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6981 static struct hda_verb alc888_6st_hp_verbs[] = {
6982 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
6983 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */
6984 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */
6985 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
6989 static struct hda_verb alc888_3st_hp_verbs[] = {
6990 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
6991 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
6992 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
6996 static struct hda_verb alc888_3st_hp_2ch_init[] = {
6997 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6998 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6999 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7000 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7004 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7005 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7006 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7007 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7008 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7012 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7013 { 2, alc888_3st_hp_2ch_init },
7014 { 6, alc888_3st_hp_6ch_init },
7017 /* toggle front-jack and RCA according to the hp-jack state */
7018 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7020 unsigned int present;
7022 present = snd_hda_codec_read(codec, 0x1b, 0,
7023 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7024 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7025 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7026 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7027 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7030 /* toggle RCA according to the front-jack state */
7031 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7033 unsigned int present;
7035 present = snd_hda_codec_read(codec, 0x14, 0,
7036 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7037 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7038 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7041 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7044 if ((res >> 26) == ALC880_HP_EVENT)
7045 alc888_lenovo_ms7195_front_automute(codec);
7046 if ((res >> 26) == ALC880_FRONT_EVENT)
7047 alc888_lenovo_ms7195_rca_automute(codec);
7050 static struct hda_verb alc883_medion_md2_verbs[] = {
7051 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7052 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7054 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7056 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7060 /* toggle speaker-output according to the hp-jack state */
7061 static void alc883_medion_md2_automute(struct hda_codec *codec)
7063 unsigned int present;
7065 present = snd_hda_codec_read(codec, 0x14, 0,
7066 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7067 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7068 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7071 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7074 if ((res >> 26) == ALC880_HP_EVENT)
7075 alc883_medion_md2_automute(codec);
7078 /* toggle speaker-output according to the hp-jack state */
7079 static void alc883_tagra_automute(struct hda_codec *codec)
7081 unsigned int present;
7084 present = snd_hda_codec_read(codec, 0x14, 0,
7085 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7086 bits = present ? HDA_AMP_MUTE : 0;
7087 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7088 HDA_AMP_MUTE, bits);
7089 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7093 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7095 if ((res >> 26) == ALC880_HP_EVENT)
7096 alc883_tagra_automute(codec);
7099 static void alc883_haier_w66_automute(struct hda_codec *codec)
7101 unsigned int present;
7104 present = snd_hda_codec_read(codec, 0x1b, 0,
7105 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7106 bits = present ? 0x80 : 0;
7107 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7111 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7114 if ((res >> 26) == ALC880_HP_EVENT)
7115 alc883_haier_w66_automute(codec);
7118 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7120 unsigned int present;
7123 present = snd_hda_codec_read(codec, 0x14, 0,
7124 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7125 bits = present ? HDA_AMP_MUTE : 0;
7126 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7127 HDA_AMP_MUTE, bits);
7130 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7132 unsigned int present;
7135 present = snd_hda_codec_read(codec, 0x1b, 0,
7136 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7137 bits = present ? HDA_AMP_MUTE : 0;
7138 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7139 HDA_AMP_MUTE, bits);
7140 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7141 HDA_AMP_MUTE, bits);
7144 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7147 if ((res >> 26) == ALC880_HP_EVENT)
7148 alc883_lenovo_101e_all_automute(codec);
7149 if ((res >> 26) == ALC880_FRONT_EVENT)
7150 alc883_lenovo_101e_ispeaker_automute(codec);
7153 /* toggle speaker-output according to the hp-jack state */
7154 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7156 unsigned int present;
7158 present = snd_hda_codec_read(codec, 0x14, 0,
7159 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7160 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7161 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7162 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7163 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7166 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7169 if ((res >> 26) == ALC880_HP_EVENT)
7170 alc883_acer_aspire_automute(codec);
7173 static struct hda_verb alc883_acer_eapd_verbs[] = {
7174 /* HP Pin: output 0 (0x0c) */
7175 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7176 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7177 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7178 /* Front Pin: output 0 (0x0c) */
7179 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7180 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7181 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7182 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7183 /* eanable EAPD on medion laptop */
7184 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7185 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7186 /* enable unsolicited event */
7187 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7192 * generic initialization of ADC, input mixers and output mixers
7194 static struct hda_verb alc883_auto_init_verbs[] = {
7196 * Unmute ADC0-2 and set the default input to mic-in
7198 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7199 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7200 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7201 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7203 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7205 * Note: PASD motherboards uses the Line In 2 as the input for
7206 * front panel mic (mic 2)
7208 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7209 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7210 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7213 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7216 * Set up output mixers (0x0c - 0x0f)
7218 /* set vol=0 to output mixers */
7219 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7220 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7221 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7222 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7223 /* set up input amps for analog loopback */
7224 /* Amp Indices: DAC = 0, mixer = 1 */
7225 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7226 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7227 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7228 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7229 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7230 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7231 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7232 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7233 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7234 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7236 /* FIXME: use matrix-type input source selection */
7237 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7239 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7240 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7241 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7242 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7243 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7245 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7246 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7247 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7248 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7249 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7254 /* capture mixer elements */
7255 static struct snd_kcontrol_new alc883_capture_mixer[] = {
7256 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7257 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7258 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7259 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7261 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7262 /* The multiple "Capture Source" controls confuse alsamixer
7263 * So call somewhat different..
7264 * FIXME: the controls appear in the "playback" view!
7266 /* .name = "Capture Source", */
7267 .name = "Input Source",
7269 .info = alc882_mux_enum_info,
7270 .get = alc882_mux_enum_get,
7271 .put = alc882_mux_enum_put,
7276 #ifdef CONFIG_SND_HDA_POWER_SAVE
7277 #define alc883_loopbacks alc880_loopbacks
7280 /* pcm configuration: identiacal with ALC880 */
7281 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
7282 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
7283 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
7284 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
7287 * configuration and preset
7289 static const char *alc883_models[ALC883_MODEL_LAST] = {
7290 [ALC883_3ST_2ch_DIG] = "3stack-dig",
7291 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
7292 [ALC883_3ST_6ch] = "3stack-6ch",
7293 [ALC883_6ST_DIG] = "6stack-dig",
7294 [ALC883_TARGA_DIG] = "targa-dig",
7295 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
7296 [ALC883_ACER] = "acer",
7297 [ALC883_ACER_ASPIRE] = "acer-aspire",
7298 [ALC883_MEDION] = "medion",
7299 [ALC883_MEDION_MD2] = "medion-md2",
7300 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
7301 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
7302 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
7303 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
7304 [ALC883_HAIER_W66] = "haier-w66",
7305 [ALC888_6ST_HP] = "6stack-hp",
7306 [ALC888_3ST_HP] = "3stack-hp",
7307 [ALC883_MITAC] = "mitac",
7308 [ALC883_AUTO] = "auto",
7311 static struct snd_pci_quirk alc883_cfg_tbl[] = {
7312 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
7313 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7314 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7315 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7316 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
7317 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
7318 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7319 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7320 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7321 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
7322 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
7323 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7324 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7325 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
7326 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
7327 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
7328 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
7329 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
7330 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
7331 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
7332 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
7333 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7334 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
7335 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
7336 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
7337 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7338 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7339 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
7340 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7341 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7342 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7343 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7344 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
7345 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
7346 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7347 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
7348 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
7349 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
7350 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
7351 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7352 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7353 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7354 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7355 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
7356 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
7360 static struct alc_config_preset alc883_presets[] = {
7361 [ALC883_3ST_2ch_DIG] = {
7362 .mixers = { alc883_3ST_2ch_mixer },
7363 .init_verbs = { alc883_init_verbs },
7364 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7365 .dac_nids = alc883_dac_nids,
7366 .dig_out_nid = ALC883_DIGOUT_NID,
7367 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7368 .adc_nids = alc883_adc_nids,
7369 .dig_in_nid = ALC883_DIGIN_NID,
7370 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7371 .channel_mode = alc883_3ST_2ch_modes,
7372 .input_mux = &alc883_capture_source,
7374 [ALC883_3ST_6ch_DIG] = {
7375 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7376 .init_verbs = { alc883_init_verbs },
7377 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7378 .dac_nids = alc883_dac_nids,
7379 .dig_out_nid = ALC883_DIGOUT_NID,
7380 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7381 .adc_nids = alc883_adc_nids,
7382 .dig_in_nid = ALC883_DIGIN_NID,
7383 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7384 .channel_mode = alc883_3ST_6ch_modes,
7386 .input_mux = &alc883_capture_source,
7388 [ALC883_3ST_6ch] = {
7389 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7390 .init_verbs = { alc883_init_verbs },
7391 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7392 .dac_nids = alc883_dac_nids,
7393 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7394 .adc_nids = alc883_adc_nids,
7395 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7396 .channel_mode = alc883_3ST_6ch_modes,
7398 .input_mux = &alc883_capture_source,
7400 [ALC883_6ST_DIG] = {
7401 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7402 .init_verbs = { alc883_init_verbs },
7403 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7404 .dac_nids = alc883_dac_nids,
7405 .dig_out_nid = ALC883_DIGOUT_NID,
7406 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7407 .adc_nids = alc883_adc_nids,
7408 .dig_in_nid = ALC883_DIGIN_NID,
7409 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7410 .channel_mode = alc883_sixstack_modes,
7411 .input_mux = &alc883_capture_source,
7413 [ALC883_TARGA_DIG] = {
7414 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7415 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7416 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7417 .dac_nids = alc883_dac_nids,
7418 .dig_out_nid = ALC883_DIGOUT_NID,
7419 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7420 .adc_nids = alc883_adc_nids,
7421 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7422 .channel_mode = alc883_3ST_6ch_modes,
7424 .input_mux = &alc883_capture_source,
7425 .unsol_event = alc883_tagra_unsol_event,
7426 .init_hook = alc883_tagra_automute,
7428 [ALC883_TARGA_2ch_DIG] = {
7429 .mixers = { alc883_tagra_2ch_mixer},
7430 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7431 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7432 .dac_nids = alc883_dac_nids,
7433 .dig_out_nid = ALC883_DIGOUT_NID,
7434 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7435 .adc_nids = alc883_adc_nids,
7436 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7437 .channel_mode = alc883_3ST_2ch_modes,
7438 .input_mux = &alc883_capture_source,
7439 .unsol_event = alc883_tagra_unsol_event,
7440 .init_hook = alc883_tagra_automute,
7443 .mixers = { alc883_base_mixer },
7444 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7445 * and the headphone jack. Turn this on and rely on the
7446 * standard mute methods whenever the user wants to turn
7447 * these outputs off.
7449 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7450 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7451 .dac_nids = alc883_dac_nids,
7452 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7453 .adc_nids = alc883_adc_nids,
7454 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7455 .channel_mode = alc883_3ST_2ch_modes,
7456 .input_mux = &alc883_capture_source,
7458 [ALC883_ACER_ASPIRE] = {
7459 .mixers = { alc883_acer_aspire_mixer },
7460 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
7461 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7462 .dac_nids = alc883_dac_nids,
7463 .dig_out_nid = ALC883_DIGOUT_NID,
7464 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7465 .adc_nids = alc883_adc_nids,
7466 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7467 .channel_mode = alc883_3ST_2ch_modes,
7468 .input_mux = &alc883_capture_source,
7469 .unsol_event = alc883_acer_aspire_unsol_event,
7470 .init_hook = alc883_acer_aspire_automute,
7473 .mixers = { alc883_fivestack_mixer,
7474 alc883_chmode_mixer },
7475 .init_verbs = { alc883_init_verbs,
7476 alc883_medion_eapd_verbs },
7477 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7478 .dac_nids = alc883_dac_nids,
7479 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7480 .adc_nids = alc883_adc_nids,
7481 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7482 .channel_mode = alc883_sixstack_modes,
7483 .input_mux = &alc883_capture_source,
7485 [ALC883_MEDION_MD2] = {
7486 .mixers = { alc883_medion_md2_mixer},
7487 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7488 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7489 .dac_nids = alc883_dac_nids,
7490 .dig_out_nid = ALC883_DIGOUT_NID,
7491 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7492 .adc_nids = alc883_adc_nids,
7493 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7494 .channel_mode = alc883_3ST_2ch_modes,
7495 .input_mux = &alc883_capture_source,
7496 .unsol_event = alc883_medion_md2_unsol_event,
7497 .init_hook = alc883_medion_md2_automute,
7499 [ALC883_LAPTOP_EAPD] = {
7500 .mixers = { alc883_base_mixer },
7501 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7502 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7503 .dac_nids = alc883_dac_nids,
7504 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7505 .adc_nids = alc883_adc_nids,
7506 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7507 .channel_mode = alc883_3ST_2ch_modes,
7508 .input_mux = &alc883_capture_source,
7510 [ALC883_LENOVO_101E_2ch] = {
7511 .mixers = { alc883_lenovo_101e_2ch_mixer},
7512 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7513 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7514 .dac_nids = alc883_dac_nids,
7515 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7516 .adc_nids = alc883_adc_nids,
7517 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7518 .channel_mode = alc883_3ST_2ch_modes,
7519 .input_mux = &alc883_lenovo_101e_capture_source,
7520 .unsol_event = alc883_lenovo_101e_unsol_event,
7521 .init_hook = alc883_lenovo_101e_all_automute,
7523 [ALC883_LENOVO_NB0763] = {
7524 .mixers = { alc883_lenovo_nb0763_mixer },
7525 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7526 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7527 .dac_nids = alc883_dac_nids,
7528 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7529 .adc_nids = alc883_adc_nids,
7530 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7531 .channel_mode = alc883_3ST_2ch_modes,
7533 .input_mux = &alc883_lenovo_nb0763_capture_source,
7534 .unsol_event = alc883_medion_md2_unsol_event,
7535 .init_hook = alc883_medion_md2_automute,
7537 [ALC888_LENOVO_MS7195_DIG] = {
7538 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7539 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7540 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7541 .dac_nids = alc883_dac_nids,
7542 .dig_out_nid = ALC883_DIGOUT_NID,
7543 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7544 .adc_nids = alc883_adc_nids,
7545 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7546 .channel_mode = alc883_3ST_6ch_modes,
7548 .input_mux = &alc883_capture_source,
7549 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7550 .init_hook = alc888_lenovo_ms7195_front_automute,
7552 [ALC883_HAIER_W66] = {
7553 .mixers = { alc883_tagra_2ch_mixer},
7554 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7555 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7556 .dac_nids = alc883_dac_nids,
7557 .dig_out_nid = ALC883_DIGOUT_NID,
7558 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7559 .adc_nids = alc883_adc_nids,
7560 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7561 .channel_mode = alc883_3ST_2ch_modes,
7562 .input_mux = &alc883_capture_source,
7563 .unsol_event = alc883_haier_w66_unsol_event,
7564 .init_hook = alc883_haier_w66_automute,
7567 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7568 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
7569 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7570 .dac_nids = alc883_dac_nids,
7571 .dig_out_nid = ALC883_DIGOUT_NID,
7572 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7573 .adc_nids = alc883_adc_nids,
7574 .dig_in_nid = ALC883_DIGIN_NID,
7575 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7576 .channel_mode = alc883_sixstack_modes,
7577 .input_mux = &alc883_capture_source,
7580 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7581 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
7582 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7583 .dac_nids = alc883_dac_nids,
7584 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7585 .adc_nids = alc883_adc_nids,
7586 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7587 .channel_mode = alc888_3st_hp_modes,
7589 .input_mux = &alc883_capture_source,
7592 .mixers = { alc883_mitac_mixer },
7593 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
7594 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7595 .dac_nids = alc883_dac_nids,
7596 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7597 .adc_nids = alc883_adc_nids,
7598 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7599 .channel_mode = alc883_3ST_2ch_modes,
7600 .input_mux = &alc883_capture_source,
7601 .unsol_event = alc883_mitac_unsol_event,
7602 .init_hook = alc883_mitac_automute,
7608 * BIOS auto configuration
7610 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7611 hda_nid_t nid, int pin_type,
7615 struct alc_spec *spec = codec->spec;
7618 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7621 idx = spec->multiout.dac_nids[dac_idx] - 2;
7623 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7625 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7627 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7631 static void alc883_auto_init_multi_out(struct hda_codec *codec)
7633 struct alc_spec *spec = codec->spec;
7636 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7637 for (i = 0; i <= HDA_SIDE; i++) {
7638 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7639 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7641 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
7646 static void alc883_auto_init_hp_out(struct hda_codec *codec)
7648 struct alc_spec *spec = codec->spec;
7651 pin = spec->autocfg.hp_pins[0];
7652 if (pin) /* connect to front */
7654 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7657 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
7658 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
7660 static void alc883_auto_init_analog_input(struct hda_codec *codec)
7662 struct alc_spec *spec = codec->spec;
7665 for (i = 0; i < AUTO_PIN_LAST; i++) {
7666 hda_nid_t nid = spec->autocfg.input_pins[i];
7667 if (alc883_is_input_pin(nid)) {
7668 snd_hda_codec_write(codec, nid, 0,
7669 AC_VERB_SET_PIN_WIDGET_CONTROL,
7670 (i <= AUTO_PIN_FRONT_MIC ?
7671 PIN_VREF80 : PIN_IN));
7672 if (nid != ALC883_PIN_CD_NID)
7673 snd_hda_codec_write(codec, nid, 0,
7674 AC_VERB_SET_AMP_GAIN_MUTE,
7680 /* almost identical with ALC880 parser... */
7681 static int alc883_parse_auto_config(struct hda_codec *codec)
7683 struct alc_spec *spec = codec->spec;
7684 int err = alc880_parse_auto_config(codec);
7689 return 0; /* no config found */
7691 err = alc_auto_add_mic_boost(codec);
7695 /* hack - override the init verbs */
7696 spec->init_verbs[0] = alc883_auto_init_verbs;
7697 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7700 return 1; /* config found */
7703 /* additional initialization for auto-configuration model */
7704 static void alc883_auto_init(struct hda_codec *codec)
7706 alc883_auto_init_multi_out(codec);
7707 alc883_auto_init_hp_out(codec);
7708 alc883_auto_init_analog_input(codec);
7711 static int patch_alc883(struct hda_codec *codec)
7713 struct alc_spec *spec;
7714 int err, board_config;
7716 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7722 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7725 if (board_config < 0) {
7726 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7727 "trying auto-probe from BIOS...\n");
7728 board_config = ALC883_AUTO;
7731 if (board_config == ALC883_AUTO) {
7732 /* automatic parse from the BIOS config */
7733 err = alc883_parse_auto_config(codec);
7739 "hda_codec: Cannot set up configuration "
7740 "from BIOS. Using base mode...\n");
7741 board_config = ALC883_3ST_2ch_DIG;
7745 if (board_config != ALC883_AUTO)
7746 setup_preset(spec, &alc883_presets[board_config]);
7748 spec->stream_name_analog = "ALC883 Analog";
7749 spec->stream_analog_playback = &alc883_pcm_analog_playback;
7750 spec->stream_analog_capture = &alc883_pcm_analog_capture;
7752 spec->stream_name_digital = "ALC883 Digital";
7753 spec->stream_digital_playback = &alc883_pcm_digital_playback;
7754 spec->stream_digital_capture = &alc883_pcm_digital_capture;
7756 if (!spec->adc_nids && spec->input_mux) {
7757 spec->adc_nids = alc883_adc_nids;
7758 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7761 codec->patch_ops = alc_patch_ops;
7762 if (board_config == ALC883_AUTO)
7763 spec->init_hook = alc883_auto_init;
7764 #ifdef CONFIG_SND_HDA_POWER_SAVE
7765 if (!spec->loopback.amplist)
7766 spec->loopback.amplist = alc883_loopbacks;
7776 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
7777 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
7779 #define alc262_dac_nids alc260_dac_nids
7780 #define alc262_adc_nids alc882_adc_nids
7781 #define alc262_adc_nids_alt alc882_adc_nids_alt
7783 #define alc262_modes alc260_modes
7784 #define alc262_capture_source alc882_capture_source
7786 static struct snd_kcontrol_new alc262_base_mixer[] = {
7787 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7788 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7789 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7790 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7791 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7792 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7793 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7794 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7795 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7796 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7797 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7798 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7799 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7800 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7801 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7802 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7803 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7804 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7808 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7809 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7810 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7811 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7812 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7813 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7814 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7815 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7816 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7817 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7818 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7819 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7820 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7821 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7822 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7823 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7824 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7828 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7829 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7830 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7831 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7832 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7833 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7835 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7836 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7837 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7838 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7839 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7840 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7841 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7842 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7843 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7844 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7845 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7846 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7847 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7848 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7852 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7853 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7854 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7855 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7856 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7857 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7858 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7859 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7860 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7861 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7862 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7863 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7864 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7865 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7866 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7867 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7871 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7872 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7873 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7874 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7878 static struct hda_bind_ctls alc262_hp_t5735_bind_front_vol = {
7879 .ops = &snd_hda_bind_vol,
7881 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7882 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
7887 static struct hda_bind_ctls alc262_hp_t5735_bind_front_sw = {
7888 .ops = &snd_hda_bind_sw,
7890 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7891 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7896 /* mute/unmute internal speaker according to the hp jack and mute state */
7897 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
7899 struct alc_spec *spec = codec->spec;
7902 if (force || !spec->sense_updated) {
7903 unsigned int present;
7904 present = snd_hda_codec_read(codec, 0x15, 0,
7905 AC_VERB_GET_PIN_SENSE, 0);
7906 spec->jack_present = (present & 0x80000000) != 0;
7907 spec->sense_updated = 1;
7909 if (spec->jack_present)
7910 mute = (0x7080 | ((0)<<8)); /* mute internal speaker */
7911 else /* unmute internal speaker if necessary */
7912 mute = (0x7000 | ((0)<<8));
7913 snd_hda_codec_write(codec, 0x0c, 0,
7914 AC_VERB_SET_AMP_GAIN_MUTE, mute );
7917 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
7920 if ((res >> 26) != ALC880_HP_EVENT)
7922 alc262_hp_t5735_automute(codec, 1);
7925 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
7927 alc262_hp_t5735_automute(codec, 1);
7930 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
7931 HDA_BIND_VOL("PCM Playback Volume", &alc262_hp_t5735_bind_front_vol),
7932 HDA_BIND_SW("PCM Playback Switch",&alc262_hp_t5735_bind_front_sw),
7933 HDA_CODEC_VOLUME("LineOut Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7934 HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7935 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7936 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7937 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7938 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7939 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7940 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7941 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7945 static struct hda_verb alc262_hp_t5735_verbs[] = {
7946 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7949 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7953 /* bind hp and internal speaker mute (with plug check) */
7954 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
7955 struct snd_ctl_elem_value *ucontrol)
7957 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7958 long *valp = ucontrol->value.integer.value;
7961 /* change hp mute */
7962 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7964 valp[0] ? 0 : HDA_AMP_MUTE);
7965 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7967 valp[1] ? 0 : HDA_AMP_MUTE);
7969 /* change speaker according to HP jack state */
7970 struct alc_spec *spec = codec->spec;
7972 if (spec->jack_present)
7973 mute = HDA_AMP_MUTE;
7975 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
7977 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7978 HDA_AMP_MUTE, mute);
7983 static struct snd_kcontrol_new alc262_sony_mixer[] = {
7984 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7986 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7987 .name = "Master Playback Switch",
7988 .info = snd_hda_mixer_amp_switch_info,
7989 .get = snd_hda_mixer_amp_switch_get,
7990 .put = alc262_sony_master_sw_put,
7991 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7993 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7994 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7995 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7996 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8000 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8001 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8002 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8003 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8004 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8005 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8006 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8007 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8011 #define alc262_capture_mixer alc882_capture_mixer
8012 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
8015 * generic initialization of ADC, input mixers and output mixers
8017 static struct hda_verb alc262_init_verbs[] = {
8019 * Unmute ADC0-2 and set the default input to mic-in
8021 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8022 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8023 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8024 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8025 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8026 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8028 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8030 * Note: PASD motherboards uses the Line In 2 as the input for
8031 * front panel mic (mic 2)
8033 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8034 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8035 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8036 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8037 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8038 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8041 * Set up output mixers (0x0c - 0x0e)
8043 /* set vol=0 to output mixers */
8044 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8045 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8046 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8047 /* set up input amps for analog loopback */
8048 /* Amp Indices: DAC = 0, mixer = 1 */
8049 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8050 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8051 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8052 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8053 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8054 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8056 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8057 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8058 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8059 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8060 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8061 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8063 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8064 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8065 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8066 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8067 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8069 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8070 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8072 /* FIXME: use matrix-type input source selection */
8073 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8074 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8075 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8076 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8077 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8078 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8080 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8081 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8082 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8083 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8085 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8088 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8093 static struct hda_verb alc262_hippo_unsol_verbs[] = {
8094 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8095 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8099 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8100 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8101 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8102 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8104 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8105 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8109 static struct hda_verb alc262_sony_unsol_verbs[] = {
8110 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8111 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8112 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
8114 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8115 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8118 /* mute/unmute internal speaker according to the hp jack and mute state */
8119 static void alc262_hippo_automute(struct hda_codec *codec)
8121 struct alc_spec *spec = codec->spec;
8123 unsigned int present;
8125 /* need to execute and sync at first */
8126 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8127 present = snd_hda_codec_read(codec, 0x15, 0,
8128 AC_VERB_GET_PIN_SENSE, 0);
8129 spec->jack_present = (present & 0x80000000) != 0;
8130 if (spec->jack_present) {
8131 /* mute internal speaker */
8132 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8133 HDA_AMP_MUTE, HDA_AMP_MUTE);
8135 /* unmute internal speaker if necessary */
8136 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8137 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8138 HDA_AMP_MUTE, mute);
8142 /* unsolicited event for HP jack sensing */
8143 static void alc262_hippo_unsol_event(struct hda_codec *codec,
8146 if ((res >> 26) != ALC880_HP_EVENT)
8148 alc262_hippo_automute(codec);
8151 static void alc262_hippo1_automute(struct hda_codec *codec)
8154 unsigned int present;
8156 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8157 present = snd_hda_codec_read(codec, 0x1b, 0,
8158 AC_VERB_GET_PIN_SENSE, 0);
8159 present = (present & 0x80000000) != 0;
8161 /* mute internal speaker */
8162 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8163 HDA_AMP_MUTE, HDA_AMP_MUTE);
8165 /* unmute internal speaker if necessary */
8166 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8167 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8168 HDA_AMP_MUTE, mute);
8172 /* unsolicited event for HP jack sensing */
8173 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8176 if ((res >> 26) != ALC880_HP_EVENT)
8178 alc262_hippo1_automute(codec);
8183 * 0x14 = headphone/spdif-out, 0x15 = internal speaker
8186 #define ALC_HP_EVENT 0x37
8188 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8189 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8190 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8194 static struct hda_input_mux alc262_fujitsu_capture_source = {
8203 static struct hda_input_mux alc262_HP_capture_source = {
8207 { "Front Mic", 0x1 },
8214 static struct hda_input_mux alc262_HP_D7000_capture_source = {
8218 { "Front Mic", 0x2 },
8224 /* mute/unmute internal speaker according to the hp jack and mute state */
8225 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8227 struct alc_spec *spec = codec->spec;
8230 if (force || !spec->sense_updated) {
8231 unsigned int present;
8232 /* need to execute and sync at first */
8233 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8234 present = snd_hda_codec_read(codec, 0x14, 0,
8235 AC_VERB_GET_PIN_SENSE, 0);
8236 spec->jack_present = (present & 0x80000000) != 0;
8237 spec->sense_updated = 1;
8239 if (spec->jack_present) {
8240 /* mute internal speaker */
8241 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8242 HDA_AMP_MUTE, HDA_AMP_MUTE);
8244 /* unmute internal speaker if necessary */
8245 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8246 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8247 HDA_AMP_MUTE, mute);
8251 /* unsolicited event for HP jack sensing */
8252 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8255 if ((res >> 26) != ALC_HP_EVENT)
8257 alc262_fujitsu_automute(codec, 1);
8260 /* bind volumes of both NID 0x0c and 0x0d */
8261 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8262 .ops = &snd_hda_bind_vol,
8264 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8265 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8270 /* bind hp and internal speaker mute (with plug check) */
8271 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8272 struct snd_ctl_elem_value *ucontrol)
8274 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8275 long *valp = ucontrol->value.integer.value;
8278 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
8280 valp[0] ? 0 : HDA_AMP_MUTE);
8281 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
8283 valp[1] ? 0 : HDA_AMP_MUTE);
8285 alc262_fujitsu_automute(codec, 0);
8289 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
8290 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
8292 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8293 .name = "Master Playback Switch",
8294 .info = snd_hda_mixer_amp_switch_info,
8295 .get = snd_hda_mixer_amp_switch_get,
8296 .put = alc262_fujitsu_master_sw_put,
8297 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8299 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8300 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8301 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8302 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8303 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8304 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8305 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8306 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8310 /* additional init verbs for Benq laptops */
8311 static struct hda_verb alc262_EAPD_verbs[] = {
8312 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8313 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8317 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8318 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8319 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8321 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8322 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8326 /* Samsung Q1 Ultra Vista model setup */
8327 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8328 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8329 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8330 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8331 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8332 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8333 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8337 static struct hda_verb alc262_ultra_verbs[] = {
8338 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8339 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8340 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8341 /* Mic is on Node 0x19 */
8342 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8343 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
8344 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8345 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
8346 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8347 {0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
8348 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8352 static struct hda_input_mux alc262_ultra_capture_source = {
8359 /* mute/unmute internal speaker according to the hp jack and mute state */
8360 static void alc262_ultra_automute(struct hda_codec *codec)
8362 struct alc_spec *spec = codec->spec;
8364 unsigned int present;
8366 /* need to execute and sync at first */
8367 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8368 present = snd_hda_codec_read(codec, 0x15, 0,
8369 AC_VERB_GET_PIN_SENSE, 0);
8370 spec->jack_present = (present & 0x80000000) != 0;
8371 if (spec->jack_present) {
8372 /* mute internal speaker */
8373 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8374 HDA_AMP_MUTE, HDA_AMP_MUTE);
8376 /* unmute internal speaker if necessary */
8377 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8378 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8379 HDA_AMP_MUTE, mute);
8383 /* unsolicited event for HP jack sensing */
8384 static void alc262_ultra_unsol_event(struct hda_codec *codec,
8387 if ((res >> 26) != ALC880_HP_EVENT)
8389 alc262_ultra_automute(codec);
8392 /* add playback controls from the parsed DAC table */
8393 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8394 const struct auto_pin_cfg *cfg)
8399 spec->multiout.num_dacs = 1; /* only use one dac */
8400 spec->multiout.dac_nids = spec->private_dac_nids;
8401 spec->multiout.dac_nids[0] = 2;
8403 nid = cfg->line_out_pins[0];
8405 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8406 "Front Playback Volume",
8407 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8410 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8411 "Front Playback Switch",
8412 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8417 nid = cfg->speaker_pins[0];
8420 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8421 "Speaker Playback Volume",
8422 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8426 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8427 "Speaker Playback Switch",
8428 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8433 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8434 "Speaker Playback Switch",
8435 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8441 nid = cfg->hp_pins[0];
8443 /* spec->multiout.hp_nid = 2; */
8445 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8446 "Headphone Playback Volume",
8447 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8451 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8452 "Headphone Playback Switch",
8453 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8458 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8459 "Headphone Playback Switch",
8460 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8469 /* identical with ALC880 */
8470 #define alc262_auto_create_analog_input_ctls \
8471 alc880_auto_create_analog_input_ctls
8474 * generic initialization of ADC, input mixers and output mixers
8476 static struct hda_verb alc262_volume_init_verbs[] = {
8478 * Unmute ADC0-2 and set the default input to mic-in
8480 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8481 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8482 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8483 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8484 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8485 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8487 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8489 * Note: PASD motherboards uses the Line In 2 as the input for
8490 * front panel mic (mic 2)
8492 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8493 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8494 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8495 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8496 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8497 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8500 * Set up output mixers (0x0c - 0x0f)
8502 /* set vol=0 to output mixers */
8503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8504 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8505 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8507 /* set up input amps for analog loopback */
8508 /* Amp Indices: DAC = 0, mixer = 1 */
8509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8510 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8511 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8512 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8513 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8514 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8516 /* FIXME: use matrix-type input source selection */
8517 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8518 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8519 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8520 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8524 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8525 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8529 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8530 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8537 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8539 * Unmute ADC0-2 and set the default input to mic-in
8541 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8542 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8543 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8544 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8545 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8546 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8548 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8550 * Note: PASD motherboards uses the Line In 2 as the input for
8551 * front panel mic (mic 2)
8553 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8554 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8555 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8556 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8557 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8558 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8559 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8560 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8563 * Set up output mixers (0x0c - 0x0e)
8565 /* set vol=0 to output mixers */
8566 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8567 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8568 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8570 /* set up input amps for analog loopback */
8571 /* Amp Indices: DAC = 0, mixer = 1 */
8572 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8573 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8574 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8575 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8576 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8577 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8579 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8580 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8581 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8583 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8584 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8586 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8587 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8590 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8591 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8592 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8593 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8595 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8596 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8597 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8598 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8599 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8600 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8603 /* FIXME: use matrix-type input source selection */
8604 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8605 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8606 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8607 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8609 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8611 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8612 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8614 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8616 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8617 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8624 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
8626 * Unmute ADC0-2 and set the default input to mic-in
8628 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8629 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8630 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8631 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8632 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8633 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8635 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8637 * Note: PASD motherboards uses the Line In 2 as the input for front
8640 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8641 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8642 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8643 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8644 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8645 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8646 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8647 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8648 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
8650 * Set up output mixers (0x0c - 0x0e)
8652 /* set vol=0 to output mixers */
8653 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8654 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8655 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8657 /* set up input amps for analog loopback */
8658 /* Amp Indices: DAC = 0, mixer = 1 */
8659 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8661 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8662 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8663 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8664 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8667 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
8668 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
8669 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
8670 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
8671 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
8672 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
8673 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
8675 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8676 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8678 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8679 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8681 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
8682 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8683 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8684 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8685 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8686 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8688 /* FIXME: use matrix-type input source selection */
8689 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8690 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8691 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
8692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
8693 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
8694 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
8695 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
8696 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8697 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
8699 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8700 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8701 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8702 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8703 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8704 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8705 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8707 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8708 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8709 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8710 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8711 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8712 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8713 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8718 #ifdef CONFIG_SND_HDA_POWER_SAVE
8719 #define alc262_loopbacks alc880_loopbacks
8722 /* pcm configuration: identiacal with ALC880 */
8723 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
8724 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
8725 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
8726 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
8729 * BIOS auto configuration
8731 static int alc262_parse_auto_config(struct hda_codec *codec)
8733 struct alc_spec *spec = codec->spec;
8735 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
8737 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8741 if (!spec->autocfg.line_outs)
8742 return 0; /* can't find valid BIOS pin config */
8743 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
8746 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
8750 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
8752 if (spec->autocfg.dig_out_pin)
8753 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
8754 if (spec->autocfg.dig_in_pin)
8755 spec->dig_in_nid = ALC262_DIGIN_NID;
8757 if (spec->kctl_alloc)
8758 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8760 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
8761 spec->num_mux_defs = 1;
8762 spec->input_mux = &spec->private_imux;
8764 err = alc_auto_add_mic_boost(codec);
8771 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
8772 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
8773 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
8776 /* init callback for auto-configuration model -- overriding the default init */
8777 static void alc262_auto_init(struct hda_codec *codec)
8779 alc262_auto_init_multi_out(codec);
8780 alc262_auto_init_hp_out(codec);
8781 alc262_auto_init_analog_input(codec);
8785 * configuration and preset
8787 static const char *alc262_models[ALC262_MODEL_LAST] = {
8788 [ALC262_BASIC] = "basic",
8789 [ALC262_HIPPO] = "hippo",
8790 [ALC262_HIPPO_1] = "hippo_1",
8791 [ALC262_FUJITSU] = "fujitsu",
8792 [ALC262_HP_BPC] = "hp-bpc",
8793 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
8794 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8795 [ALC262_BENQ_ED8] = "benq",
8796 [ALC262_BENQ_T31] = "benq-t31",
8797 [ALC262_SONY_ASSAMD] = "sony-assamd",
8798 [ALC262_ULTRA] = "ultra",
8799 [ALC262_AUTO] = "auto",
8802 static struct snd_pci_quirk alc262_cfg_tbl[] = {
8803 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
8804 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
8805 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
8806 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
8807 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
8808 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
8809 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
8810 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
8811 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
8812 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
8813 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
8814 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
8815 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
8816 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
8817 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
8818 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
8819 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
8820 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
8821 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
8822 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
8823 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
8824 ALC262_HP_TC_T5735),
8825 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8826 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
8827 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8828 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8829 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
8830 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
8831 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
8832 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
8833 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
8834 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
8838 static struct alc_config_preset alc262_presets[] = {
8840 .mixers = { alc262_base_mixer },
8841 .init_verbs = { alc262_init_verbs },
8842 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8843 .dac_nids = alc262_dac_nids,
8845 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8846 .channel_mode = alc262_modes,
8847 .input_mux = &alc262_capture_source,
8850 .mixers = { alc262_base_mixer },
8851 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
8852 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8853 .dac_nids = alc262_dac_nids,
8855 .dig_out_nid = ALC262_DIGOUT_NID,
8856 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8857 .channel_mode = alc262_modes,
8858 .input_mux = &alc262_capture_source,
8859 .unsol_event = alc262_hippo_unsol_event,
8860 .init_hook = alc262_hippo_automute,
8862 [ALC262_HIPPO_1] = {
8863 .mixers = { alc262_hippo1_mixer },
8864 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
8865 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8866 .dac_nids = alc262_dac_nids,
8868 .dig_out_nid = ALC262_DIGOUT_NID,
8869 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8870 .channel_mode = alc262_modes,
8871 .input_mux = &alc262_capture_source,
8872 .unsol_event = alc262_hippo1_unsol_event,
8873 .init_hook = alc262_hippo1_automute,
8875 [ALC262_FUJITSU] = {
8876 .mixers = { alc262_fujitsu_mixer },
8877 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
8878 alc262_fujitsu_unsol_verbs },
8879 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8880 .dac_nids = alc262_dac_nids,
8882 .dig_out_nid = ALC262_DIGOUT_NID,
8883 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8884 .channel_mode = alc262_modes,
8885 .input_mux = &alc262_fujitsu_capture_source,
8886 .unsol_event = alc262_fujitsu_unsol_event,
8889 .mixers = { alc262_HP_BPC_mixer },
8890 .init_verbs = { alc262_HP_BPC_init_verbs },
8891 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8892 .dac_nids = alc262_dac_nids,
8894 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8895 .channel_mode = alc262_modes,
8896 .input_mux = &alc262_HP_capture_source,
8898 [ALC262_HP_BPC_D7000_WF] = {
8899 .mixers = { alc262_HP_BPC_WildWest_mixer },
8900 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8901 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8902 .dac_nids = alc262_dac_nids,
8904 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8905 .channel_mode = alc262_modes,
8906 .input_mux = &alc262_HP_D7000_capture_source,
8908 [ALC262_HP_BPC_D7000_WL] = {
8909 .mixers = { alc262_HP_BPC_WildWest_mixer,
8910 alc262_HP_BPC_WildWest_option_mixer },
8911 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8912 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8913 .dac_nids = alc262_dac_nids,
8915 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8916 .channel_mode = alc262_modes,
8917 .input_mux = &alc262_HP_D7000_capture_source,
8919 [ALC262_HP_TC_T5735] = {
8920 .mixers = { alc262_hp_t5735_mixer },
8921 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
8922 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8923 .dac_nids = alc262_dac_nids,
8925 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8926 .channel_mode = alc262_modes,
8927 .input_mux = &alc262_capture_source,
8928 .unsol_event = alc262_hp_t5735_unsol_event,
8929 .init_hook = alc262_hp_t5735_init_hook,
8931 [ALC262_BENQ_ED8] = {
8932 .mixers = { alc262_base_mixer },
8933 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8934 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8935 .dac_nids = alc262_dac_nids,
8937 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8938 .channel_mode = alc262_modes,
8939 .input_mux = &alc262_capture_source,
8941 [ALC262_SONY_ASSAMD] = {
8942 .mixers = { alc262_sony_mixer },
8943 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8944 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8945 .dac_nids = alc262_dac_nids,
8947 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8948 .channel_mode = alc262_modes,
8949 .input_mux = &alc262_capture_source,
8950 .unsol_event = alc262_hippo_unsol_event,
8951 .init_hook = alc262_hippo_automute,
8953 [ALC262_BENQ_T31] = {
8954 .mixers = { alc262_benq_t31_mixer },
8955 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8956 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8957 .dac_nids = alc262_dac_nids,
8959 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8960 .channel_mode = alc262_modes,
8961 .input_mux = &alc262_capture_source,
8962 .unsol_event = alc262_hippo_unsol_event,
8963 .init_hook = alc262_hippo_automute,
8966 .mixers = { alc262_ultra_mixer },
8967 .init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
8968 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8969 .dac_nids = alc262_dac_nids,
8971 .dig_out_nid = ALC262_DIGOUT_NID,
8972 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8973 .channel_mode = alc262_modes,
8974 .input_mux = &alc262_ultra_capture_source,
8975 .unsol_event = alc262_ultra_unsol_event,
8976 .init_hook = alc262_ultra_automute,
8980 static int patch_alc262(struct hda_codec *codec)
8982 struct alc_spec *spec;
8986 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8992 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
8997 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8998 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8999 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9000 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
9004 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9008 if (board_config < 0) {
9009 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
9010 "trying auto-probe from BIOS...\n");
9011 board_config = ALC262_AUTO;
9014 if (board_config == ALC262_AUTO) {
9015 /* automatic parse from the BIOS config */
9016 err = alc262_parse_auto_config(codec);
9022 "hda_codec: Cannot set up configuration "
9023 "from BIOS. Using base mode...\n");
9024 board_config = ALC262_BASIC;
9028 if (board_config != ALC262_AUTO)
9029 setup_preset(spec, &alc262_presets[board_config]);
9031 spec->stream_name_analog = "ALC262 Analog";
9032 spec->stream_analog_playback = &alc262_pcm_analog_playback;
9033 spec->stream_analog_capture = &alc262_pcm_analog_capture;
9035 spec->stream_name_digital = "ALC262 Digital";
9036 spec->stream_digital_playback = &alc262_pcm_digital_playback;
9037 spec->stream_digital_capture = &alc262_pcm_digital_capture;
9039 if (!spec->adc_nids && spec->input_mux) {
9040 /* check whether NID 0x07 is valid */
9041 unsigned int wcap = get_wcaps(codec, 0x07);
9044 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9045 if (wcap != AC_WID_AUD_IN) {
9046 spec->adc_nids = alc262_adc_nids_alt;
9047 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
9048 spec->mixers[spec->num_mixers] =
9049 alc262_capture_alt_mixer;
9052 spec->adc_nids = alc262_adc_nids;
9053 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
9054 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
9059 codec->patch_ops = alc_patch_ops;
9060 if (board_config == ALC262_AUTO)
9061 spec->init_hook = alc262_auto_init;
9062 #ifdef CONFIG_SND_HDA_POWER_SAVE
9063 if (!spec->loopback.amplist)
9064 spec->loopback.amplist = alc262_loopbacks;
9071 * ALC268 channel source setting (2 channel)
9073 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
9074 #define alc268_modes alc260_modes
9076 static hda_nid_t alc268_dac_nids[2] = {
9081 static hda_nid_t alc268_adc_nids[2] = {
9086 static hda_nid_t alc268_adc_nids_alt[1] = {
9091 static struct snd_kcontrol_new alc268_base_mixer[] = {
9092 /* output mixer control */
9093 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9094 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9095 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9096 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9097 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9098 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9099 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9103 static struct hda_verb alc268_eapd_verbs[] = {
9104 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9105 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9109 /* Toshiba specific */
9110 #define alc268_toshiba_automute alc262_hippo_automute
9112 static struct hda_verb alc268_toshiba_verbs[] = {
9113 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9118 /* bind volumes of both NID 0x02 and 0x03 */
9119 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
9120 .ops = &snd_hda_bind_vol,
9122 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
9123 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
9128 /* mute/unmute internal speaker according to the hp jack and mute state */
9129 static void alc268_acer_automute(struct hda_codec *codec, int force)
9131 struct alc_spec *spec = codec->spec;
9134 if (force || !spec->sense_updated) {
9135 unsigned int present;
9136 present = snd_hda_codec_read(codec, 0x14, 0,
9137 AC_VERB_GET_PIN_SENSE, 0);
9138 spec->jack_present = (present & 0x80000000) != 0;
9139 spec->sense_updated = 1;
9141 if (spec->jack_present)
9142 mute = HDA_AMP_MUTE; /* mute internal speaker */
9143 else /* unmute internal speaker if necessary */
9144 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9145 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9146 HDA_AMP_MUTE, mute);
9150 /* bind hp and internal speaker mute (with plug check) */
9151 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
9152 struct snd_ctl_elem_value *ucontrol)
9154 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9155 long *valp = ucontrol->value.integer.value;
9158 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9160 valp[0] ? 0 : HDA_AMP_MUTE);
9161 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9163 valp[1] ? 0 : HDA_AMP_MUTE);
9165 alc268_acer_automute(codec, 0);
9169 static struct snd_kcontrol_new alc268_acer_mixer[] = {
9170 /* output mixer control */
9171 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9173 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9174 .name = "Master Playback Switch",
9175 .info = snd_hda_mixer_amp_switch_info,
9176 .get = snd_hda_mixer_amp_switch_get,
9177 .put = alc268_acer_master_sw_put,
9178 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9180 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9181 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9182 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9186 static struct hda_verb alc268_acer_verbs[] = {
9187 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9188 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9190 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9194 /* unsolicited event for HP jack sensing */
9195 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9198 if ((res >> 26) != ALC880_HP_EVENT)
9200 alc268_toshiba_automute(codec);
9203 static void alc268_acer_unsol_event(struct hda_codec *codec,
9206 if ((res >> 26) != ALC880_HP_EVENT)
9208 alc268_acer_automute(codec, 1);
9211 static void alc268_acer_init_hook(struct hda_codec *codec)
9213 alc268_acer_automute(codec, 1);
9217 * generic initialization of ADC, input mixers and output mixers
9219 static struct hda_verb alc268_base_init_verbs[] = {
9220 /* Unmute DAC0-1 and set vol = 0 */
9221 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9222 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9223 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9224 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9225 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9226 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9229 * Set up output mixers (0x0c - 0x0e)
9231 /* set vol=0 to output mixers */
9232 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9233 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9234 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9235 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
9237 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9238 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9240 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9241 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9242 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9243 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9244 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9245 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9246 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9247 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9249 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9250 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9251 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9252 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9253 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9254 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9255 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9256 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9258 /* Unmute Selector 23h,24h and set the default input to mic-in */
9260 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
9261 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9262 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
9263 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9269 * generic initialization of ADC, input mixers and output mixers
9271 static struct hda_verb alc268_volume_init_verbs[] = {
9272 /* set output DAC */
9273 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9274 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9275 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9276 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9278 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9279 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9280 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9281 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9282 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9284 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9285 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9286 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9287 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9288 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9290 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9291 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9292 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9293 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9295 /* set PCBEEP vol = 0 */
9296 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
9301 #define alc268_mux_enum_info alc_mux_enum_info
9302 #define alc268_mux_enum_get alc_mux_enum_get
9304 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
9305 struct snd_ctl_elem_value *ucontrol)
9307 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9308 struct alc_spec *spec = codec->spec;
9310 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9311 static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
9312 hda_nid_t nid = capture_mixers[adc_idx];
9314 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
9316 &spec->cur_mux[adc_idx]);
9319 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9320 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9321 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9323 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9324 /* The multiple "Capture Source" controls confuse alsamixer
9325 * So call somewhat different..
9326 * FIXME: the controls appear in the "playback" view!
9328 /* .name = "Capture Source", */
9329 .name = "Input Source",
9331 .info = alc268_mux_enum_info,
9332 .get = alc268_mux_enum_get,
9333 .put = alc268_mux_enum_put,
9338 static struct snd_kcontrol_new alc268_capture_mixer[] = {
9339 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9340 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9341 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9342 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9344 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9345 /* The multiple "Capture Source" controls confuse alsamixer
9346 * So call somewhat different..
9347 * FIXME: the controls appear in the "playback" view!
9349 /* .name = "Capture Source", */
9350 .name = "Input Source",
9352 .info = alc268_mux_enum_info,
9353 .get = alc268_mux_enum_get,
9354 .put = alc268_mux_enum_put,
9359 static struct hda_input_mux alc268_capture_source = {
9363 { "Front Mic", 0x1 },
9369 /* create input playback/capture controls for the given pin */
9370 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9371 const char *ctlname, int idx)
9376 sprintf(name, "%s Playback Volume", ctlname);
9378 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9379 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9383 } else if (nid == 0x15) {
9384 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9385 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9391 sprintf(name, "%s Playback Switch", ctlname);
9392 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9393 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9399 /* add playback controls from the parsed DAC table */
9400 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9401 const struct auto_pin_cfg *cfg)
9406 spec->multiout.num_dacs = 2; /* only use one dac */
9407 spec->multiout.dac_nids = spec->private_dac_nids;
9408 spec->multiout.dac_nids[0] = 2;
9409 spec->multiout.dac_nids[1] = 3;
9411 nid = cfg->line_out_pins[0];
9413 alc268_new_analog_output(spec, nid, "Front", 0);
9415 nid = cfg->speaker_pins[0];
9417 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9418 "Speaker Playback Volume",
9419 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9423 nid = cfg->hp_pins[0];
9425 alc268_new_analog_output(spec, nid, "Headphone", 0);
9427 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
9429 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9430 "Mono Playback Switch",
9431 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
9438 /* create playback/capture controls for input pins */
9439 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
9440 const struct auto_pin_cfg *cfg)
9442 struct hda_input_mux *imux = &spec->private_imux;
9445 for (i = 0; i < AUTO_PIN_LAST; i++) {
9446 switch(cfg->input_pins[i]) {
9448 idx1 = 0; /* Mic 1 */
9451 idx1 = 1; /* Mic 2 */
9454 idx1 = 2; /* Line In */
9462 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9463 imux->items[imux->num_items].index = idx1;
9469 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
9471 struct alc_spec *spec = codec->spec;
9472 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9473 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9474 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9475 unsigned int dac_vol1, dac_vol2;
9478 snd_hda_codec_write(codec, speaker_nid, 0,
9479 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
9480 snd_hda_codec_write(codec, 0x0f, 0,
9481 AC_VERB_SET_AMP_GAIN_MUTE,
9483 snd_hda_codec_write(codec, 0x10, 0,
9484 AC_VERB_SET_AMP_GAIN_MUTE,
9487 snd_hda_codec_write(codec, 0x0f, 0,
9488 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9489 snd_hda_codec_write(codec, 0x10, 0,
9490 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9493 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
9494 if (line_nid == 0x14)
9495 dac_vol2 = AMP_OUT_ZERO;
9496 else if (line_nid == 0x15)
9497 dac_vol1 = AMP_OUT_ZERO;
9499 dac_vol2 = AMP_OUT_ZERO;
9500 else if (hp_nid == 0x15)
9501 dac_vol1 = AMP_OUT_ZERO;
9502 if (line_nid != 0x16 || hp_nid != 0x16 ||
9503 spec->autocfg.line_out_pins[1] != 0x16 ||
9504 spec->autocfg.line_out_pins[2] != 0x16)
9505 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
9507 snd_hda_codec_write(codec, 0x02, 0,
9508 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
9509 snd_hda_codec_write(codec, 0x03, 0,
9510 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
9513 /* pcm configuration: identiacal with ALC880 */
9514 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
9515 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
9516 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
9519 * BIOS auto configuration
9521 static int alc268_parse_auto_config(struct hda_codec *codec)
9523 struct alc_spec *spec = codec->spec;
9525 static hda_nid_t alc268_ignore[] = { 0 };
9527 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9531 if (!spec->autocfg.line_outs)
9532 return 0; /* can't find valid BIOS pin config */
9534 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
9537 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
9541 spec->multiout.max_channels = 2;
9543 /* digital only support output */
9544 if (spec->autocfg.dig_out_pin)
9545 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
9547 if (spec->kctl_alloc)
9548 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9550 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
9551 spec->num_mux_defs = 1;
9552 spec->input_mux = &spec->private_imux;
9554 err = alc_auto_add_mic_boost(codec);
9561 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
9562 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
9563 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
9565 /* init callback for auto-configuration model -- overriding the default init */
9566 static void alc268_auto_init(struct hda_codec *codec)
9568 alc268_auto_init_multi_out(codec);
9569 alc268_auto_init_hp_out(codec);
9570 alc268_auto_init_mono_speaker_out(codec);
9571 alc268_auto_init_analog_input(codec);
9575 * configuration and preset
9577 static const char *alc268_models[ALC268_MODEL_LAST] = {
9578 [ALC268_3ST] = "3stack",
9579 [ALC268_TOSHIBA] = "toshiba",
9580 [ALC268_ACER] = "acer",
9581 [ALC268_AUTO] = "auto",
9584 static struct snd_pci_quirk alc268_cfg_tbl[] = {
9585 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
9586 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
9587 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
9588 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
9589 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
9590 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
9591 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
9595 static struct alc_config_preset alc268_presets[] = {
9597 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9598 .init_verbs = { alc268_base_init_verbs },
9599 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9600 .dac_nids = alc268_dac_nids,
9601 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9602 .adc_nids = alc268_adc_nids_alt,
9604 .dig_out_nid = ALC268_DIGOUT_NID,
9605 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9606 .channel_mode = alc268_modes,
9607 .input_mux = &alc268_capture_source,
9609 [ALC268_TOSHIBA] = {
9610 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9611 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9612 alc268_toshiba_verbs },
9613 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9614 .dac_nids = alc268_dac_nids,
9615 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9616 .adc_nids = alc268_adc_nids_alt,
9618 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9619 .channel_mode = alc268_modes,
9620 .input_mux = &alc268_capture_source,
9621 .unsol_event = alc268_toshiba_unsol_event,
9622 .init_hook = alc268_toshiba_automute,
9625 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
9626 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9627 alc268_acer_verbs },
9628 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9629 .dac_nids = alc268_dac_nids,
9630 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9631 .adc_nids = alc268_adc_nids_alt,
9633 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9634 .channel_mode = alc268_modes,
9635 .input_mux = &alc268_capture_source,
9636 .unsol_event = alc268_acer_unsol_event,
9637 .init_hook = alc268_acer_init_hook,
9641 static int patch_alc268(struct hda_codec *codec)
9643 struct alc_spec *spec;
9647 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
9653 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
9657 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9658 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
9659 "trying auto-probe from BIOS...\n");
9660 board_config = ALC268_AUTO;
9663 if (board_config == ALC268_AUTO) {
9664 /* automatic parse from the BIOS config */
9665 err = alc268_parse_auto_config(codec);
9671 "hda_codec: Cannot set up configuration "
9672 "from BIOS. Using base mode...\n");
9673 board_config = ALC268_3ST;
9677 if (board_config != ALC268_AUTO)
9678 setup_preset(spec, &alc268_presets[board_config]);
9680 spec->stream_name_analog = "ALC268 Analog";
9681 spec->stream_analog_playback = &alc268_pcm_analog_playback;
9682 spec->stream_analog_capture = &alc268_pcm_analog_capture;
9684 spec->stream_name_digital = "ALC268 Digital";
9685 spec->stream_digital_playback = &alc268_pcm_digital_playback;
9687 if (board_config == ALC268_AUTO) {
9688 if (!spec->adc_nids && spec->input_mux) {
9689 /* check whether NID 0x07 is valid */
9690 unsigned int wcap = get_wcaps(codec, 0x07);
9693 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9694 if (wcap != AC_WID_AUD_IN) {
9695 spec->adc_nids = alc268_adc_nids_alt;
9696 spec->num_adc_nids =
9697 ARRAY_SIZE(alc268_adc_nids_alt);
9698 spec->mixers[spec->num_mixers] =
9699 alc268_capture_alt_mixer;
9702 spec->adc_nids = alc268_adc_nids;
9703 spec->num_adc_nids =
9704 ARRAY_SIZE(alc268_adc_nids);
9705 spec->mixers[spec->num_mixers] =
9706 alc268_capture_mixer;
9711 codec->patch_ops = alc_patch_ops;
9712 if (board_config == ALC268_AUTO)
9713 spec->init_hook = alc268_auto_init;
9719 * ALC269 channel source setting (2 channel)
9721 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
9723 #define alc269_dac_nids alc260_dac_nids
9725 static hda_nid_t alc269_adc_nids[1] = {
9730 #define alc269_modes alc260_modes
9731 #define alc269_capture_source alc880_lg_lw_capture_source
9733 static struct snd_kcontrol_new alc269_base_mixer[] = {
9734 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9735 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9736 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9737 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9738 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9739 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9740 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9741 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9742 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9743 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9744 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9745 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9749 /* capture mixer elements */
9750 static struct snd_kcontrol_new alc269_capture_mixer[] = {
9751 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9752 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9754 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9755 /* The multiple "Capture Source" controls confuse alsamixer
9756 * So call somewhat different..
9757 * FIXME: the controls appear in the "playback" view!
9759 /* .name = "Capture Source", */
9760 .name = "Input Source",
9762 .info = alc_mux_enum_info,
9763 .get = alc_mux_enum_get,
9764 .put = alc_mux_enum_put,
9770 * generic initialization of ADC, input mixers and output mixers
9772 static struct hda_verb alc269_init_verbs[] = {
9774 * Unmute ADC0 and set the default input to mic-in
9776 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9778 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
9779 * analog-loopback mixer widget
9780 * Note: PASD motherboards uses the Line In 2 as the input for
9781 * front panel mic (mic 2)
9783 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9784 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9785 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9786 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9787 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9788 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9791 * Set up output mixers (0x0c - 0x0e)
9793 /* set vol=0 to output mixers */
9794 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9795 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9797 /* set up input amps for analog loopback */
9798 /* Amp Indices: DAC = 0, mixer = 1 */
9799 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9800 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9801 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9802 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9803 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9804 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9806 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9807 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9808 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9809 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9810 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9811 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9812 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9814 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9815 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9816 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9817 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9818 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9819 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9820 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9822 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9823 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9825 /* FIXME: use matrix-type input source selection */
9826 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
9827 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9828 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9829 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9830 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9831 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9834 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9835 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9839 /* add playback controls from the parsed DAC table */
9840 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
9841 const struct auto_pin_cfg *cfg)
9846 spec->multiout.num_dacs = 1; /* only use one dac */
9847 spec->multiout.dac_nids = spec->private_dac_nids;
9848 spec->multiout.dac_nids[0] = 2;
9850 nid = cfg->line_out_pins[0];
9852 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9853 "Front Playback Volume",
9854 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
9857 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9858 "Front Playback Switch",
9859 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9864 nid = cfg->speaker_pins[0];
9866 if (!cfg->line_out_pins[0]) {
9867 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9868 "Speaker Playback Volume",
9869 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
9875 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9876 "Speaker Playback Switch",
9877 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9882 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9883 "Speaker Playback Switch",
9884 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9890 nid = cfg->hp_pins[0];
9892 /* spec->multiout.hp_nid = 2; */
9893 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
9894 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9895 "Headphone Playback Volume",
9896 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
9902 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9903 "Headphone Playback Switch",
9904 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9909 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9910 "Headphone Playback Switch",
9911 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9920 #define alc269_auto_create_analog_input_ctls \
9921 alc880_auto_create_analog_input_ctls
9923 #ifdef CONFIG_SND_HDA_POWER_SAVE
9924 #define alc269_loopbacks alc880_loopbacks
9927 /* pcm configuration: identiacal with ALC880 */
9928 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
9929 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
9930 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
9931 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
9934 * BIOS auto configuration
9936 static int alc269_parse_auto_config(struct hda_codec *codec)
9938 struct alc_spec *spec = codec->spec;
9940 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
9942 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9947 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
9950 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
9954 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9956 if (spec->autocfg.dig_out_pin)
9957 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
9959 if (spec->kctl_alloc)
9960 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9962 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
9963 spec->num_mux_defs = 1;
9964 spec->input_mux = &spec->private_imux;
9966 err = alc_auto_add_mic_boost(codec);
9973 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
9974 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
9975 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
9978 /* init callback for auto-configuration model -- overriding the default init */
9979 static void alc269_auto_init(struct hda_codec *codec)
9981 alc269_auto_init_multi_out(codec);
9982 alc269_auto_init_hp_out(codec);
9983 alc269_auto_init_analog_input(codec);
9987 * configuration and preset
9989 static const char *alc269_models[ALC269_MODEL_LAST] = {
9990 [ALC269_BASIC] = "basic",
9993 static struct snd_pci_quirk alc269_cfg_tbl[] = {
9997 static struct alc_config_preset alc269_presets[] = {
9999 .mixers = { alc269_base_mixer },
10000 .init_verbs = { alc269_init_verbs },
10001 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
10002 .dac_nids = alc269_dac_nids,
10004 .num_channel_mode = ARRAY_SIZE(alc269_modes),
10005 .channel_mode = alc269_modes,
10006 .input_mux = &alc269_capture_source,
10010 static int patch_alc269(struct hda_codec *codec)
10012 struct alc_spec *spec;
10016 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10020 codec->spec = spec;
10022 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
10026 if (board_config < 0) {
10027 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
10028 "trying auto-probe from BIOS...\n");
10029 board_config = ALC269_AUTO;
10032 if (board_config == ALC269_AUTO) {
10033 /* automatic parse from the BIOS config */
10034 err = alc269_parse_auto_config(codec);
10040 "hda_codec: Cannot set up configuration "
10041 "from BIOS. Using base mode...\n");
10042 board_config = ALC269_BASIC;
10046 if (board_config != ALC269_AUTO)
10047 setup_preset(spec, &alc269_presets[board_config]);
10049 spec->stream_name_analog = "ALC269 Analog";
10050 spec->stream_analog_playback = &alc269_pcm_analog_playback;
10051 spec->stream_analog_capture = &alc269_pcm_analog_capture;
10053 spec->stream_name_digital = "ALC269 Digital";
10054 spec->stream_digital_playback = &alc269_pcm_digital_playback;
10055 spec->stream_digital_capture = &alc269_pcm_digital_capture;
10057 spec->adc_nids = alc269_adc_nids;
10058 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
10059 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
10060 spec->num_mixers++;
10062 codec->patch_ops = alc_patch_ops;
10063 if (board_config == ALC269_AUTO)
10064 spec->init_hook = alc269_auto_init;
10065 #ifdef CONFIG_SND_HDA_POWER_SAVE
10066 if (!spec->loopback.amplist)
10067 spec->loopback.amplist = alc269_loopbacks;
10074 * ALC861 channel source setting (2/6 channel selection for 3-stack)
10078 * set the path ways for 2 channel output
10079 * need to set the codec line out and mic 1 pin widgets to inputs
10081 static struct hda_verb alc861_threestack_ch2_init[] = {
10082 /* set pin widget 1Ah (line in) for input */
10083 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10084 /* set pin widget 18h (mic1/2) for input, for mic also enable
10087 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10089 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10091 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10092 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10098 * need to set the codec line out and mic 1 pin widgets to outputs
10100 static struct hda_verb alc861_threestack_ch6_init[] = {
10101 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10102 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10103 /* set pin widget 18h (mic1) for output (CLFE)*/
10104 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10106 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10107 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10109 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10111 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10112 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10117 static struct hda_channel_mode alc861_threestack_modes[2] = {
10118 { 2, alc861_threestack_ch2_init },
10119 { 6, alc861_threestack_ch6_init },
10121 /* Set mic1 as input and unmute the mixer */
10122 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
10123 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10124 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10127 /* Set mic1 as output and mute mixer */
10128 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
10129 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10130 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10134 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
10135 { 2, alc861_uniwill_m31_ch2_init },
10136 { 4, alc861_uniwill_m31_ch4_init },
10139 /* Set mic1 and line-in as input and unmute the mixer */
10140 static struct hda_verb alc861_asus_ch2_init[] = {
10141 /* set pin widget 1Ah (line in) for input */
10142 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10143 /* set pin widget 18h (mic1/2) for input, for mic also enable
10146 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10148 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10150 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10151 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10155 /* Set mic1 nad line-in as output and mute mixer */
10156 static struct hda_verb alc861_asus_ch6_init[] = {
10157 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10158 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10159 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10160 /* set pin widget 18h (mic1) for output (CLFE)*/
10161 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10162 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10163 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10164 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10166 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10168 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10169 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10174 static struct hda_channel_mode alc861_asus_modes[2] = {
10175 { 2, alc861_asus_ch2_init },
10176 { 6, alc861_asus_ch6_init },
10181 static struct snd_kcontrol_new alc861_base_mixer[] = {
10182 /* output mixer control */
10183 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10184 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10185 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10186 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10187 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10189 /*Input mixer control */
10190 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10191 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10192 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10193 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10194 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10195 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10196 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10197 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10198 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10199 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10201 /* Capture mixer control */
10202 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10203 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10206 .name = "Capture Source",
10208 .info = alc_mux_enum_info,
10209 .get = alc_mux_enum_get,
10210 .put = alc_mux_enum_put,
10215 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
10216 /* output mixer control */
10217 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10218 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10219 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10220 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10221 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10223 /* Input mixer control */
10224 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10225 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10226 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10227 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10228 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10229 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10230 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10231 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10232 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10233 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10235 /* Capture mixer control */
10236 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10237 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10240 .name = "Capture Source",
10242 .info = alc_mux_enum_info,
10243 .get = alc_mux_enum_get,
10244 .put = alc_mux_enum_put,
10247 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10248 .name = "Channel Mode",
10249 .info = alc_ch_mode_info,
10250 .get = alc_ch_mode_get,
10251 .put = alc_ch_mode_put,
10252 .private_value = ARRAY_SIZE(alc861_threestack_modes),
10257 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
10258 /* output mixer control */
10259 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10260 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10261 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10263 /*Capture mixer control */
10264 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10265 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10267 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10268 .name = "Capture Source",
10270 .info = alc_mux_enum_info,
10271 .get = alc_mux_enum_get,
10272 .put = alc_mux_enum_put,
10278 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
10279 /* output mixer control */
10280 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10281 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10282 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10283 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10284 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10286 /* Input mixer control */
10287 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10288 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10289 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10290 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10291 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10292 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10293 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10294 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10295 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10296 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10298 /* Capture mixer control */
10299 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10300 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10302 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10303 .name = "Capture Source",
10305 .info = alc_mux_enum_info,
10306 .get = alc_mux_enum_get,
10307 .put = alc_mux_enum_put,
10310 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10311 .name = "Channel Mode",
10312 .info = alc_ch_mode_info,
10313 .get = alc_ch_mode_get,
10314 .put = alc_ch_mode_put,
10315 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
10320 static struct snd_kcontrol_new alc861_asus_mixer[] = {
10321 /* output mixer control */
10322 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10323 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10324 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10325 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10326 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10328 /* Input mixer control */
10329 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10330 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10331 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10332 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10333 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10334 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10336 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10337 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10338 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
10340 /* Capture mixer control */
10341 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10342 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10344 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10345 .name = "Capture Source",
10347 .info = alc_mux_enum_info,
10348 .get = alc_mux_enum_get,
10349 .put = alc_mux_enum_put,
10352 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10353 .name = "Channel Mode",
10354 .info = alc_ch_mode_info,
10355 .get = alc_ch_mode_get,
10356 .put = alc_ch_mode_put,
10357 .private_value = ARRAY_SIZE(alc861_asus_modes),
10362 /* additional mixer */
10363 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
10364 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10365 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10366 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
10367 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
10372 * generic initialization of ADC, input mixers and output mixers
10374 static struct hda_verb alc861_base_init_verbs[] = {
10376 * Unmute ADC0 and set the default input to mic-in
10378 /* port-A for surround (rear panel) */
10379 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10380 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
10381 /* port-B for mic-in (rear panel) with vref */
10382 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10383 /* port-C for line-in (rear panel) */
10384 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10385 /* port-D for Front */
10386 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10387 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10388 /* port-E for HP out (front panel) */
10389 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10390 /* route front PCM to HP */
10391 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10392 /* port-F for mic-in (front panel) with vref */
10393 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10394 /* port-G for CLFE (rear panel) */
10395 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10396 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10397 /* port-H for side (rear panel) */
10398 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10399 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
10401 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10402 /* route front mic to ADC1*/
10403 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10404 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10406 /* Unmute DAC0~3 & spdif out*/
10407 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10408 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10409 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10410 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10411 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10413 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10414 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10415 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10416 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10417 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10419 /* Unmute Stereo Mixer 15 */
10420 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10421 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10423 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10425 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10426 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10427 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10428 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10429 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10430 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10431 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10432 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10433 /* hp used DAC 3 (Front) */
10434 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10435 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10440 static struct hda_verb alc861_threestack_init_verbs[] = {
10442 * Unmute ADC0 and set the default input to mic-in
10444 /* port-A for surround (rear panel) */
10445 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10446 /* port-B for mic-in (rear panel) with vref */
10447 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10448 /* port-C for line-in (rear panel) */
10449 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10450 /* port-D for Front */
10451 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10452 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10453 /* port-E for HP out (front panel) */
10454 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10455 /* route front PCM to HP */
10456 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10457 /* port-F for mic-in (front panel) with vref */
10458 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10459 /* port-G for CLFE (rear panel) */
10460 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10461 /* port-H for side (rear panel) */
10462 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10464 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10465 /* route front mic to ADC1*/
10466 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10467 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10468 /* Unmute DAC0~3 & spdif out*/
10469 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10470 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10471 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10472 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10473 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10475 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10476 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10477 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10478 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10479 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10481 /* Unmute Stereo Mixer 15 */
10482 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10483 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10484 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10485 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10487 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10488 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10489 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10490 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10491 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10492 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10493 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10494 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10495 /* hp used DAC 3 (Front) */
10496 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10497 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10501 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
10503 * Unmute ADC0 and set the default input to mic-in
10505 /* port-A for surround (rear panel) */
10506 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10507 /* port-B for mic-in (rear panel) with vref */
10508 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10509 /* port-C for line-in (rear panel) */
10510 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10511 /* port-D for Front */
10512 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10513 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10514 /* port-E for HP out (front panel) */
10515 /* this has to be set to VREF80 */
10516 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10517 /* route front PCM to HP */
10518 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10519 /* port-F for mic-in (front panel) with vref */
10520 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10521 /* port-G for CLFE (rear panel) */
10522 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10523 /* port-H for side (rear panel) */
10524 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10526 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10527 /* route front mic to ADC1*/
10528 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10529 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10530 /* Unmute DAC0~3 & spdif out*/
10531 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10532 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10533 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10534 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10537 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10538 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10539 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10540 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10541 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10543 /* Unmute Stereo Mixer 15 */
10544 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10545 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10546 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10547 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10549 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10550 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10551 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10552 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10553 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10554 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10555 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10556 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10557 /* hp used DAC 3 (Front) */
10558 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10559 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10563 static struct hda_verb alc861_asus_init_verbs[] = {
10565 * Unmute ADC0 and set the default input to mic-in
10567 /* port-A for surround (rear panel)
10568 * according to codec#0 this is the HP jack
10570 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
10571 /* route front PCM to HP */
10572 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
10573 /* port-B for mic-in (rear panel) with vref */
10574 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10575 /* port-C for line-in (rear panel) */
10576 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10577 /* port-D for Front */
10578 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10579 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10580 /* port-E for HP out (front panel) */
10581 /* this has to be set to VREF80 */
10582 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10583 /* route front PCM to HP */
10584 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10585 /* port-F for mic-in (front panel) with vref */
10586 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10587 /* port-G for CLFE (rear panel) */
10588 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10589 /* port-H for side (rear panel) */
10590 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10592 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10593 /* route front mic to ADC1*/
10594 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10595 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10596 /* Unmute DAC0~3 & spdif out*/
10597 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10598 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10599 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10600 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10601 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10602 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10603 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10604 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10605 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10606 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10608 /* Unmute Stereo Mixer 15 */
10609 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10611 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10612 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10614 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10615 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10616 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10617 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10618 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10619 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10620 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10621 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10622 /* hp used DAC 3 (Front) */
10623 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10624 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10628 /* additional init verbs for ASUS laptops */
10629 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
10630 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
10631 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
10636 * generic initialization of ADC, input mixers and output mixers
10638 static struct hda_verb alc861_auto_init_verbs[] = {
10640 * Unmute ADC0 and set the default input to mic-in
10642 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
10643 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10645 /* Unmute DAC0~3 & spdif out*/
10646 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10647 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10648 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10649 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10650 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10652 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10653 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10654 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10655 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10656 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10658 /* Unmute Stereo Mixer 15 */
10659 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10660 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10662 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
10664 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10665 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10666 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10667 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10668 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10669 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10670 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10671 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10673 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10674 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10675 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10676 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10677 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10678 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10679 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10680 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10682 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
10687 static struct hda_verb alc861_toshiba_init_verbs[] = {
10688 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10693 /* toggle speaker-output according to the hp-jack state */
10694 static void alc861_toshiba_automute(struct hda_codec *codec)
10696 unsigned int present;
10698 present = snd_hda_codec_read(codec, 0x0f, 0,
10699 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10700 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
10701 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10702 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
10703 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
10706 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
10709 if ((res >> 26) == ALC880_HP_EVENT)
10710 alc861_toshiba_automute(codec);
10713 /* pcm configuration: identiacal with ALC880 */
10714 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
10715 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
10716 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
10717 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
10720 #define ALC861_DIGOUT_NID 0x07
10722 static struct hda_channel_mode alc861_8ch_modes[1] = {
10726 static hda_nid_t alc861_dac_nids[4] = {
10727 /* front, surround, clfe, side */
10728 0x03, 0x06, 0x05, 0x04
10731 static hda_nid_t alc660_dac_nids[3] = {
10732 /* front, clfe, surround */
10736 static hda_nid_t alc861_adc_nids[1] = {
10741 static struct hda_input_mux alc861_capture_source = {
10745 { "Front Mic", 0x3 },
10752 /* fill in the dac_nids table from the parsed pin configuration */
10753 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
10754 const struct auto_pin_cfg *cfg)
10759 spec->multiout.dac_nids = spec->private_dac_nids;
10760 for (i = 0; i < cfg->line_outs; i++) {
10761 nid = cfg->line_out_pins[i];
10763 if (i >= ARRAY_SIZE(alc861_dac_nids))
10765 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
10768 spec->multiout.num_dacs = cfg->line_outs;
10772 /* add playback controls from the parsed DAC table */
10773 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
10774 const struct auto_pin_cfg *cfg)
10777 static const char *chname[4] = {
10778 "Front", "Surround", NULL /*CLFE*/, "Side"
10783 for (i = 0; i < cfg->line_outs; i++) {
10784 nid = spec->multiout.dac_nids[i];
10789 err = add_control(spec, ALC_CTL_BIND_MUTE,
10790 "Center Playback Switch",
10791 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
10795 err = add_control(spec, ALC_CTL_BIND_MUTE,
10796 "LFE Playback Switch",
10797 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10802 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
10804 if (nid == alc861_dac_nids[idx])
10806 sprintf(name, "%s Playback Switch", chname[idx]);
10807 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10808 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10817 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
10825 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
10827 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10828 "Headphone Playback Switch",
10829 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10832 spec->multiout.hp_nid = nid;
10837 /* create playback/capture controls for input pins */
10838 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
10839 const struct auto_pin_cfg *cfg)
10841 struct hda_input_mux *imux = &spec->private_imux;
10842 int i, err, idx, idx1;
10844 for (i = 0; i < AUTO_PIN_LAST; i++) {
10845 switch (cfg->input_pins[i]) {
10848 idx = 2; /* Line In */
10852 idx = 2; /* Line In */
10856 idx = 1; /* Mic In */
10860 idx = 1; /* Mic In */
10870 err = new_analog_input(spec, cfg->input_pins[i],
10871 auto_pin_cfg_labels[i], idx, 0x15);
10875 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
10876 imux->items[imux->num_items].index = idx1;
10882 static struct snd_kcontrol_new alc861_capture_mixer[] = {
10883 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10884 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10887 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10888 /* The multiple "Capture Source" controls confuse alsamixer
10889 * So call somewhat different..
10890 *FIXME: the controls appear in the "playback" view!
10892 /* .name = "Capture Source", */
10893 .name = "Input Source",
10895 .info = alc_mux_enum_info,
10896 .get = alc_mux_enum_get,
10897 .put = alc_mux_enum_put,
10902 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
10904 int pin_type, int dac_idx)
10906 /* set as output */
10908 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10910 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
10915 static void alc861_auto_init_multi_out(struct hda_codec *codec)
10917 struct alc_spec *spec = codec->spec;
10920 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
10921 for (i = 0; i < spec->autocfg.line_outs; i++) {
10922 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10923 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10925 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
10926 spec->multiout.dac_nids[i]);
10930 static void alc861_auto_init_hp_out(struct hda_codec *codec)
10932 struct alc_spec *spec = codec->spec;
10935 pin = spec->autocfg.hp_pins[0];
10936 if (pin) /* connect to front */
10937 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
10938 spec->multiout.dac_nids[0]);
10941 static void alc861_auto_init_analog_input(struct hda_codec *codec)
10943 struct alc_spec *spec = codec->spec;
10946 for (i = 0; i < AUTO_PIN_LAST; i++) {
10947 hda_nid_t nid = spec->autocfg.input_pins[i];
10948 if (nid >= 0x0c && nid <= 0x11) {
10949 snd_hda_codec_write(codec, nid, 0,
10950 AC_VERB_SET_PIN_WIDGET_CONTROL,
10951 i <= AUTO_PIN_FRONT_MIC ?
10952 PIN_VREF80 : PIN_IN);
10957 /* parse the BIOS configuration and set up the alc_spec */
10958 /* return 1 if successful, 0 if the proper config is not found,
10959 * or a negative error code
10961 static int alc861_parse_auto_config(struct hda_codec *codec)
10963 struct alc_spec *spec = codec->spec;
10965 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
10967 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10971 if (!spec->autocfg.line_outs)
10972 return 0; /* can't find valid BIOS pin config */
10974 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
10977 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
10980 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
10983 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
10987 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10989 if (spec->autocfg.dig_out_pin)
10990 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
10992 if (spec->kctl_alloc)
10993 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10995 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
10997 spec->num_mux_defs = 1;
10998 spec->input_mux = &spec->private_imux;
11000 spec->adc_nids = alc861_adc_nids;
11001 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
11002 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
11003 spec->num_mixers++;
11008 /* additional initialization for auto-configuration model */
11009 static void alc861_auto_init(struct hda_codec *codec)
11011 alc861_auto_init_multi_out(codec);
11012 alc861_auto_init_hp_out(codec);
11013 alc861_auto_init_analog_input(codec);
11016 #ifdef CONFIG_SND_HDA_POWER_SAVE
11017 static struct hda_amp_list alc861_loopbacks[] = {
11018 { 0x15, HDA_INPUT, 0 },
11019 { 0x15, HDA_INPUT, 1 },
11020 { 0x15, HDA_INPUT, 2 },
11021 { 0x15, HDA_INPUT, 3 },
11028 * configuration and preset
11030 static const char *alc861_models[ALC861_MODEL_LAST] = {
11031 [ALC861_3ST] = "3stack",
11032 [ALC660_3ST] = "3stack-660",
11033 [ALC861_3ST_DIG] = "3stack-dig",
11034 [ALC861_6ST_DIG] = "6stack-dig",
11035 [ALC861_UNIWILL_M31] = "uniwill-m31",
11036 [ALC861_TOSHIBA] = "toshiba",
11037 [ALC861_ASUS] = "asus",
11038 [ALC861_ASUS_LAPTOP] = "asus-laptop",
11039 [ALC861_AUTO] = "auto",
11042 static struct snd_pci_quirk alc861_cfg_tbl[] = {
11043 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
11044 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11045 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11046 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
11047 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
11048 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
11049 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
11050 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
11051 * Any other models that need this preset?
11053 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
11054 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
11055 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
11056 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
11057 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
11058 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
11059 /* FIXME: the below seems conflict */
11060 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
11061 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
11062 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
11066 static struct alc_config_preset alc861_presets[] = {
11068 .mixers = { alc861_3ST_mixer },
11069 .init_verbs = { alc861_threestack_init_verbs },
11070 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11071 .dac_nids = alc861_dac_nids,
11072 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11073 .channel_mode = alc861_threestack_modes,
11075 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11076 .adc_nids = alc861_adc_nids,
11077 .input_mux = &alc861_capture_source,
11079 [ALC861_3ST_DIG] = {
11080 .mixers = { alc861_base_mixer },
11081 .init_verbs = { alc861_threestack_init_verbs },
11082 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11083 .dac_nids = alc861_dac_nids,
11084 .dig_out_nid = ALC861_DIGOUT_NID,
11085 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11086 .channel_mode = alc861_threestack_modes,
11088 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11089 .adc_nids = alc861_adc_nids,
11090 .input_mux = &alc861_capture_source,
11092 [ALC861_6ST_DIG] = {
11093 .mixers = { alc861_base_mixer },
11094 .init_verbs = { alc861_base_init_verbs },
11095 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11096 .dac_nids = alc861_dac_nids,
11097 .dig_out_nid = ALC861_DIGOUT_NID,
11098 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
11099 .channel_mode = alc861_8ch_modes,
11100 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11101 .adc_nids = alc861_adc_nids,
11102 .input_mux = &alc861_capture_source,
11105 .mixers = { alc861_3ST_mixer },
11106 .init_verbs = { alc861_threestack_init_verbs },
11107 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
11108 .dac_nids = alc660_dac_nids,
11109 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11110 .channel_mode = alc861_threestack_modes,
11112 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11113 .adc_nids = alc861_adc_nids,
11114 .input_mux = &alc861_capture_source,
11116 [ALC861_UNIWILL_M31] = {
11117 .mixers = { alc861_uniwill_m31_mixer },
11118 .init_verbs = { alc861_uniwill_m31_init_verbs },
11119 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11120 .dac_nids = alc861_dac_nids,
11121 .dig_out_nid = ALC861_DIGOUT_NID,
11122 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
11123 .channel_mode = alc861_uniwill_m31_modes,
11125 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11126 .adc_nids = alc861_adc_nids,
11127 .input_mux = &alc861_capture_source,
11129 [ALC861_TOSHIBA] = {
11130 .mixers = { alc861_toshiba_mixer },
11131 .init_verbs = { alc861_base_init_verbs,
11132 alc861_toshiba_init_verbs },
11133 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11134 .dac_nids = alc861_dac_nids,
11135 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11136 .channel_mode = alc883_3ST_2ch_modes,
11137 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11138 .adc_nids = alc861_adc_nids,
11139 .input_mux = &alc861_capture_source,
11140 .unsol_event = alc861_toshiba_unsol_event,
11141 .init_hook = alc861_toshiba_automute,
11144 .mixers = { alc861_asus_mixer },
11145 .init_verbs = { alc861_asus_init_verbs },
11146 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11147 .dac_nids = alc861_dac_nids,
11148 .dig_out_nid = ALC861_DIGOUT_NID,
11149 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
11150 .channel_mode = alc861_asus_modes,
11153 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11154 .adc_nids = alc861_adc_nids,
11155 .input_mux = &alc861_capture_source,
11157 [ALC861_ASUS_LAPTOP] = {
11158 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
11159 .init_verbs = { alc861_asus_init_verbs,
11160 alc861_asus_laptop_init_verbs },
11161 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11162 .dac_nids = alc861_dac_nids,
11163 .dig_out_nid = ALC861_DIGOUT_NID,
11164 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11165 .channel_mode = alc883_3ST_2ch_modes,
11167 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11168 .adc_nids = alc861_adc_nids,
11169 .input_mux = &alc861_capture_source,
11174 static int patch_alc861(struct hda_codec *codec)
11176 struct alc_spec *spec;
11180 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11184 codec->spec = spec;
11186 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
11190 if (board_config < 0) {
11191 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
11192 "trying auto-probe from BIOS...\n");
11193 board_config = ALC861_AUTO;
11196 if (board_config == ALC861_AUTO) {
11197 /* automatic parse from the BIOS config */
11198 err = alc861_parse_auto_config(codec);
11204 "hda_codec: Cannot set up configuration "
11205 "from BIOS. Using base mode...\n");
11206 board_config = ALC861_3ST_DIG;
11210 if (board_config != ALC861_AUTO)
11211 setup_preset(spec, &alc861_presets[board_config]);
11213 spec->stream_name_analog = "ALC861 Analog";
11214 spec->stream_analog_playback = &alc861_pcm_analog_playback;
11215 spec->stream_analog_capture = &alc861_pcm_analog_capture;
11217 spec->stream_name_digital = "ALC861 Digital";
11218 spec->stream_digital_playback = &alc861_pcm_digital_playback;
11219 spec->stream_digital_capture = &alc861_pcm_digital_capture;
11221 codec->patch_ops = alc_patch_ops;
11222 if (board_config == ALC861_AUTO)
11223 spec->init_hook = alc861_auto_init;
11224 #ifdef CONFIG_SND_HDA_POWER_SAVE
11225 if (!spec->loopback.amplist)
11226 spec->loopback.amplist = alc861_loopbacks;
11233 * ALC861-VD support
11237 * In addition, an independent DAC
11239 #define ALC861VD_DIGOUT_NID 0x06
11241 static hda_nid_t alc861vd_dac_nids[4] = {
11242 /* front, surr, clfe, side surr */
11243 0x02, 0x03, 0x04, 0x05
11246 /* dac_nids for ALC660vd are in a different order - according to
11247 * Realtek's driver.
11248 * This should probably tesult in a different mixer for 6stack models
11249 * of ALC660vd codecs, but for now there is only 3stack mixer
11250 * - and it is the same as in 861vd.
11251 * adc_nids in ALC660vd are (is) the same as in 861vd
11253 static hda_nid_t alc660vd_dac_nids[3] = {
11254 /* front, rear, clfe, rear_surr */
11258 static hda_nid_t alc861vd_adc_nids[1] = {
11264 /* FIXME: should be a matrix-type input source selection */
11265 static struct hda_input_mux alc861vd_capture_source = {
11269 { "Front Mic", 0x1 },
11275 static struct hda_input_mux alc861vd_dallas_capture_source = {
11278 { "Front Mic", 0x0 },
11279 { "ATAPI Mic", 0x1 },
11280 { "Line In", 0x5 },
11284 static struct hda_input_mux alc861vd_hp_capture_source = {
11287 { "Front Mic", 0x0 },
11288 { "ATAPI Mic", 0x1 },
11292 #define alc861vd_mux_enum_info alc_mux_enum_info
11293 #define alc861vd_mux_enum_get alc_mux_enum_get
11295 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
11296 struct snd_ctl_elem_value *ucontrol)
11298 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11299 struct alc_spec *spec = codec->spec;
11300 const struct hda_input_mux *imux = spec->input_mux;
11301 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
11302 static hda_nid_t capture_mixers[1] = { 0x22 };
11303 hda_nid_t nid = capture_mixers[adc_idx];
11304 unsigned int *cur_val = &spec->cur_mux[adc_idx];
11305 unsigned int i, idx;
11307 idx = ucontrol->value.enumerated.item[0];
11308 if (idx >= imux->num_items)
11309 idx = imux->num_items - 1;
11310 if (*cur_val == idx)
11312 for (i = 0; i < imux->num_items; i++) {
11313 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
11314 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
11315 imux->items[i].index,
11325 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
11332 static struct hda_verb alc861vd_6stack_ch6_init[] = {
11333 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11334 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11335 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11336 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11343 static struct hda_verb alc861vd_6stack_ch8_init[] = {
11344 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11345 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11346 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11347 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11351 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
11352 { 6, alc861vd_6stack_ch6_init },
11353 { 8, alc861vd_6stack_ch8_init },
11356 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
11358 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11359 .name = "Channel Mode",
11360 .info = alc_ch_mode_info,
11361 .get = alc_ch_mode_get,
11362 .put = alc_ch_mode_put,
11367 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
11368 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11369 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11372 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11373 /* The multiple "Capture Source" controls confuse alsamixer
11374 * So call somewhat different..
11375 *FIXME: the controls appear in the "playback" view!
11377 /* .name = "Capture Source", */
11378 .name = "Input Source",
11380 .info = alc861vd_mux_enum_info,
11381 .get = alc861vd_mux_enum_get,
11382 .put = alc861vd_mux_enum_put,
11387 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11388 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11390 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
11391 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11392 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11394 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11395 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
11397 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
11399 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
11401 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11402 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
11404 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
11405 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
11407 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11409 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11410 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11411 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11413 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11414 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11415 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11417 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11418 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11420 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11421 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11423 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11424 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11429 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
11430 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11431 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11433 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11435 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11437 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11439 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11440 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11441 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11443 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11444 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11446 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11447 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11449 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11450 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11455 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
11456 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11457 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
11458 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11460 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11462 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11463 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11464 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11466 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11467 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11468 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11470 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11471 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11476 /* Pin assignment: Front=0x14, HP = 0x15,
11477 * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
11479 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
11480 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11481 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11482 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11483 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11484 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11485 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11486 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11487 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11488 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
11489 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
11493 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
11494 * Front Mic=0x18, ATAPI Mic = 0x19,
11496 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
11497 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11498 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11499 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11500 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11501 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11502 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11503 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11504 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11510 * generic initialization of ADC, input mixers and output mixers
11512 static struct hda_verb alc861vd_volume_init_verbs[] = {
11514 * Unmute ADC0 and set the default input to mic-in
11516 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11517 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11519 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
11520 * the analog-loopback mixer widget
11522 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11523 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11524 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11525 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11526 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11527 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11529 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
11530 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11536 * Set up output mixers (0x02 - 0x05)
11538 /* set vol=0 to output mixers */
11539 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11540 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11541 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11542 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11544 /* set up input amps for analog loopback */
11545 /* Amp Indices: DAC = 0, mixer = 1 */
11546 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11547 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11548 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11549 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11550 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11551 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11552 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11553 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11559 * 3-stack pin configuration:
11560 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
11562 static struct hda_verb alc861vd_3stack_init_verbs[] = {
11564 * Set pin mode and muting
11566 /* set front pin widgets 0x14 for output */
11567 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11568 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11569 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11571 /* Mic (rear) pin: input vref at 80% */
11572 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11573 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11574 /* Front Mic pin: input vref at 80% */
11575 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11576 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11577 /* Line In pin: input */
11578 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11579 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11580 /* Line-2 In: Headphone output (output 0 - 0x0c) */
11581 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11582 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11583 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11584 /* CD pin widget for input */
11585 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11591 * 6-stack pin configuration:
11593 static struct hda_verb alc861vd_6stack_init_verbs[] = {
11595 * Set pin mode and muting
11597 /* set front pin widgets 0x14 for output */
11598 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11599 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11600 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11602 /* Rear Pin: output 1 (0x0d) */
11603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11604 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11605 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11606 /* CLFE Pin: output 2 (0x0e) */
11607 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11608 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11609 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
11610 /* Side Pin: output 3 (0x0f) */
11611 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11612 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11613 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
11615 /* Mic (rear) pin: input vref at 80% */
11616 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11617 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11618 /* Front Mic pin: input vref at 80% */
11619 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11620 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11621 /* Line In pin: input */
11622 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11623 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11624 /* Line-2 In: Headphone output (output 0 - 0x0c) */
11625 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11626 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11627 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11628 /* CD pin widget for input */
11629 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11634 static struct hda_verb alc861vd_eapd_verbs[] = {
11635 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11639 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
11640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11641 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11642 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11643 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11644 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11648 /* toggle speaker-output according to the hp-jack state */
11649 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
11651 unsigned int present;
11652 unsigned char bits;
11654 present = snd_hda_codec_read(codec, 0x1b, 0,
11655 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11656 bits = present ? HDA_AMP_MUTE : 0;
11657 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11658 HDA_AMP_MUTE, bits);
11661 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
11663 unsigned int present;
11664 unsigned char bits;
11666 present = snd_hda_codec_read(codec, 0x18, 0,
11667 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11668 bits = present ? HDA_AMP_MUTE : 0;
11669 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
11670 HDA_AMP_MUTE, bits);
11673 static void alc861vd_lenovo_automute(struct hda_codec *codec)
11675 alc861vd_lenovo_hp_automute(codec);
11676 alc861vd_lenovo_mic_automute(codec);
11679 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
11682 switch (res >> 26) {
11683 case ALC880_HP_EVENT:
11684 alc861vd_lenovo_hp_automute(codec);
11686 case ALC880_MIC_EVENT:
11687 alc861vd_lenovo_mic_automute(codec);
11692 static struct hda_verb alc861vd_dallas_verbs[] = {
11693 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11694 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11695 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11696 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11698 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11699 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11700 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11701 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11702 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11703 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11704 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11705 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11708 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11709 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11710 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11711 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11712 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11713 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11714 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11716 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11717 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11718 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11719 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11720 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11721 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11722 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11723 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11725 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11726 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11727 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11728 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11730 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11731 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11732 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11737 /* toggle speaker-output according to the hp-jack state */
11738 static void alc861vd_dallas_automute(struct hda_codec *codec)
11740 unsigned int present;
11742 present = snd_hda_codec_read(codec, 0x15, 0,
11743 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11744 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11745 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11748 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
11750 if ((res >> 26) == ALC880_HP_EVENT)
11751 alc861vd_dallas_automute(codec);
11754 #ifdef CONFIG_SND_HDA_POWER_SAVE
11755 #define alc861vd_loopbacks alc880_loopbacks
11758 /* pcm configuration: identiacal with ALC880 */
11759 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
11760 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
11761 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
11762 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
11765 * configuration and preset
11767 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
11768 [ALC660VD_3ST] = "3stack-660",
11769 [ALC660VD_3ST_DIG] = "3stack-660-digout",
11770 [ALC861VD_3ST] = "3stack",
11771 [ALC861VD_3ST_DIG] = "3stack-digout",
11772 [ALC861VD_6ST_DIG] = "6stack-digout",
11773 [ALC861VD_LENOVO] = "lenovo",
11774 [ALC861VD_DALLAS] = "dallas",
11775 [ALC861VD_HP] = "hp",
11776 [ALC861VD_AUTO] = "auto",
11779 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
11780 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
11781 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
11782 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
11783 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
11784 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
11785 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
11786 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
11787 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
11788 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
11789 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
11790 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
11791 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
11792 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
11793 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
11797 static struct alc_config_preset alc861vd_presets[] = {
11799 .mixers = { alc861vd_3st_mixer },
11800 .init_verbs = { alc861vd_volume_init_verbs,
11801 alc861vd_3stack_init_verbs },
11802 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11803 .dac_nids = alc660vd_dac_nids,
11804 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11805 .adc_nids = alc861vd_adc_nids,
11806 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11807 .channel_mode = alc861vd_3stack_2ch_modes,
11808 .input_mux = &alc861vd_capture_source,
11810 [ALC660VD_3ST_DIG] = {
11811 .mixers = { alc861vd_3st_mixer },
11812 .init_verbs = { alc861vd_volume_init_verbs,
11813 alc861vd_3stack_init_verbs },
11814 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11815 .dac_nids = alc660vd_dac_nids,
11816 .dig_out_nid = ALC861VD_DIGOUT_NID,
11817 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11818 .adc_nids = alc861vd_adc_nids,
11819 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11820 .channel_mode = alc861vd_3stack_2ch_modes,
11821 .input_mux = &alc861vd_capture_source,
11824 .mixers = { alc861vd_3st_mixer },
11825 .init_verbs = { alc861vd_volume_init_verbs,
11826 alc861vd_3stack_init_verbs },
11827 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11828 .dac_nids = alc861vd_dac_nids,
11829 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11830 .channel_mode = alc861vd_3stack_2ch_modes,
11831 .input_mux = &alc861vd_capture_source,
11833 [ALC861VD_3ST_DIG] = {
11834 .mixers = { alc861vd_3st_mixer },
11835 .init_verbs = { alc861vd_volume_init_verbs,
11836 alc861vd_3stack_init_verbs },
11837 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11838 .dac_nids = alc861vd_dac_nids,
11839 .dig_out_nid = ALC861VD_DIGOUT_NID,
11840 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11841 .channel_mode = alc861vd_3stack_2ch_modes,
11842 .input_mux = &alc861vd_capture_source,
11844 [ALC861VD_6ST_DIG] = {
11845 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
11846 .init_verbs = { alc861vd_volume_init_verbs,
11847 alc861vd_6stack_init_verbs },
11848 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11849 .dac_nids = alc861vd_dac_nids,
11850 .dig_out_nid = ALC861VD_DIGOUT_NID,
11851 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
11852 .channel_mode = alc861vd_6stack_modes,
11853 .input_mux = &alc861vd_capture_source,
11855 [ALC861VD_LENOVO] = {
11856 .mixers = { alc861vd_lenovo_mixer },
11857 .init_verbs = { alc861vd_volume_init_verbs,
11858 alc861vd_3stack_init_verbs,
11859 alc861vd_eapd_verbs,
11860 alc861vd_lenovo_unsol_verbs },
11861 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11862 .dac_nids = alc660vd_dac_nids,
11863 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11864 .adc_nids = alc861vd_adc_nids,
11865 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11866 .channel_mode = alc861vd_3stack_2ch_modes,
11867 .input_mux = &alc861vd_capture_source,
11868 .unsol_event = alc861vd_lenovo_unsol_event,
11869 .init_hook = alc861vd_lenovo_automute,
11871 [ALC861VD_DALLAS] = {
11872 .mixers = { alc861vd_dallas_mixer },
11873 .init_verbs = { alc861vd_dallas_verbs },
11874 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11875 .dac_nids = alc861vd_dac_nids,
11876 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11877 .adc_nids = alc861vd_adc_nids,
11878 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11879 .channel_mode = alc861vd_3stack_2ch_modes,
11880 .input_mux = &alc861vd_dallas_capture_source,
11881 .unsol_event = alc861vd_dallas_unsol_event,
11882 .init_hook = alc861vd_dallas_automute,
11885 .mixers = { alc861vd_hp_mixer },
11886 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
11887 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11888 .dac_nids = alc861vd_dac_nids,
11889 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11890 .dig_out_nid = ALC861VD_DIGOUT_NID,
11891 .adc_nids = alc861vd_adc_nids,
11892 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11893 .channel_mode = alc861vd_3stack_2ch_modes,
11894 .input_mux = &alc861vd_hp_capture_source,
11895 .unsol_event = alc861vd_dallas_unsol_event,
11896 .init_hook = alc861vd_dallas_automute,
11901 * BIOS auto configuration
11903 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
11904 hda_nid_t nid, int pin_type, int dac_idx)
11906 /* set as output */
11907 snd_hda_codec_write(codec, nid, 0,
11908 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11909 snd_hda_codec_write(codec, nid, 0,
11910 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11913 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
11915 struct alc_spec *spec = codec->spec;
11918 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
11919 for (i = 0; i <= HDA_SIDE; i++) {
11920 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11921 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11923 alc861vd_auto_set_output_and_unmute(codec, nid,
11929 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
11931 struct alc_spec *spec = codec->spec;
11934 pin = spec->autocfg.hp_pins[0];
11935 if (pin) /* connect to front and use dac 0 */
11936 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11939 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
11940 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
11942 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
11944 struct alc_spec *spec = codec->spec;
11947 for (i = 0; i < AUTO_PIN_LAST; i++) {
11948 hda_nid_t nid = spec->autocfg.input_pins[i];
11949 if (alc861vd_is_input_pin(nid)) {
11950 snd_hda_codec_write(codec, nid, 0,
11951 AC_VERB_SET_PIN_WIDGET_CONTROL,
11952 i <= AUTO_PIN_FRONT_MIC ?
11953 PIN_VREF80 : PIN_IN);
11954 if (nid != ALC861VD_PIN_CD_NID)
11955 snd_hda_codec_write(codec, nid, 0,
11956 AC_VERB_SET_AMP_GAIN_MUTE,
11962 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
11963 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
11965 /* add playback controls from the parsed DAC table */
11966 /* Based on ALC880 version. But ALC861VD has separate,
11967 * different NIDs for mute/unmute switch and volume control */
11968 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
11969 const struct auto_pin_cfg *cfg)
11972 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
11973 hda_nid_t nid_v, nid_s;
11976 for (i = 0; i < cfg->line_outs; i++) {
11977 if (!spec->multiout.dac_nids[i])
11979 nid_v = alc861vd_idx_to_mixer_vol(
11981 spec->multiout.dac_nids[i]));
11982 nid_s = alc861vd_idx_to_mixer_switch(
11984 spec->multiout.dac_nids[i]));
11988 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11989 "Center Playback Volume",
11990 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
11994 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11995 "LFE Playback Volume",
11996 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
12000 err = add_control(spec, ALC_CTL_BIND_MUTE,
12001 "Center Playback Switch",
12002 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
12006 err = add_control(spec, ALC_CTL_BIND_MUTE,
12007 "LFE Playback Switch",
12008 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
12013 sprintf(name, "%s Playback Volume", chname[i]);
12014 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12015 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
12019 sprintf(name, "%s Playback Switch", chname[i]);
12020 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12021 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
12030 /* add playback controls for speaker and HP outputs */
12031 /* Based on ALC880 version. But ALC861VD has separate,
12032 * different NIDs for mute/unmute switch and volume control */
12033 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
12034 hda_nid_t pin, const char *pfx)
12036 hda_nid_t nid_v, nid_s;
12043 if (alc880_is_fixed_pin(pin)) {
12044 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12045 /* specify the DAC as the extra output */
12046 if (!spec->multiout.hp_nid)
12047 spec->multiout.hp_nid = nid_v;
12049 spec->multiout.extra_out_nid[0] = nid_v;
12050 /* control HP volume/switch on the output mixer amp */
12051 nid_v = alc861vd_idx_to_mixer_vol(
12052 alc880_fixed_pin_idx(pin));
12053 nid_s = alc861vd_idx_to_mixer_switch(
12054 alc880_fixed_pin_idx(pin));
12056 sprintf(name, "%s Playback Volume", pfx);
12057 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12058 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
12061 sprintf(name, "%s Playback Switch", pfx);
12062 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12063 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
12066 } else if (alc880_is_multi_pin(pin)) {
12067 /* set manual connection */
12068 /* we have only a switch on HP-out PIN */
12069 sprintf(name, "%s Playback Switch", pfx);
12070 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12071 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12078 /* parse the BIOS configuration and set up the alc_spec
12079 * return 1 if successful, 0 if the proper config is not found,
12080 * or a negative error code
12081 * Based on ALC880 version - had to change it to override
12082 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
12083 static int alc861vd_parse_auto_config(struct hda_codec *codec)
12085 struct alc_spec *spec = codec->spec;
12087 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
12089 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12093 if (!spec->autocfg.line_outs)
12094 return 0; /* can't find valid BIOS pin config */
12096 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12099 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
12102 err = alc861vd_auto_create_extra_out(spec,
12103 spec->autocfg.speaker_pins[0],
12107 err = alc861vd_auto_create_extra_out(spec,
12108 spec->autocfg.hp_pins[0],
12112 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
12116 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12118 if (spec->autocfg.dig_out_pin)
12119 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
12121 if (spec->kctl_alloc)
12122 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12124 spec->init_verbs[spec->num_init_verbs++]
12125 = alc861vd_volume_init_verbs;
12127 spec->num_mux_defs = 1;
12128 spec->input_mux = &spec->private_imux;
12130 err = alc_auto_add_mic_boost(codec);
12137 /* additional initialization for auto-configuration model */
12138 static void alc861vd_auto_init(struct hda_codec *codec)
12140 alc861vd_auto_init_multi_out(codec);
12141 alc861vd_auto_init_hp_out(codec);
12142 alc861vd_auto_init_analog_input(codec);
12145 static int patch_alc861vd(struct hda_codec *codec)
12147 struct alc_spec *spec;
12148 int err, board_config;
12150 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12154 codec->spec = spec;
12156 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
12160 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
12161 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
12162 "ALC861VD, trying auto-probe from BIOS...\n");
12163 board_config = ALC861VD_AUTO;
12166 if (board_config == ALC861VD_AUTO) {
12167 /* automatic parse from the BIOS config */
12168 err = alc861vd_parse_auto_config(codec);
12174 "hda_codec: Cannot set up configuration "
12175 "from BIOS. Using base mode...\n");
12176 board_config = ALC861VD_3ST;
12180 if (board_config != ALC861VD_AUTO)
12181 setup_preset(spec, &alc861vd_presets[board_config]);
12183 spec->stream_name_analog = "ALC861VD Analog";
12184 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
12185 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
12187 spec->stream_name_digital = "ALC861VD Digital";
12188 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
12189 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
12191 spec->adc_nids = alc861vd_adc_nids;
12192 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
12194 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
12195 spec->num_mixers++;
12197 codec->patch_ops = alc_patch_ops;
12199 if (board_config == ALC861VD_AUTO)
12200 spec->init_hook = alc861vd_auto_init;
12201 #ifdef CONFIG_SND_HDA_POWER_SAVE
12202 if (!spec->loopback.amplist)
12203 spec->loopback.amplist = alc861vd_loopbacks;
12212 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
12213 * configuration. Each pin widget can choose any input DACs and a mixer.
12214 * Each ADC is connected from a mixer of all inputs. This makes possible
12215 * 6-channel independent captures.
12217 * In addition, an independent DAC for the multi-playback (not used in this
12220 #define ALC662_DIGOUT_NID 0x06
12221 #define ALC662_DIGIN_NID 0x0a
12223 static hda_nid_t alc662_dac_nids[4] = {
12224 /* front, rear, clfe, rear_surr */
12228 static hda_nid_t alc662_adc_nids[1] = {
12233 /* FIXME: should be a matrix-type input source selection */
12235 static struct hda_input_mux alc662_capture_source = {
12239 { "Front Mic", 0x1 },
12245 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
12253 static struct hda_input_mux alc662_eeepc_capture_source = {
12261 #define alc662_mux_enum_info alc_mux_enum_info
12262 #define alc662_mux_enum_get alc_mux_enum_get
12264 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
12265 struct snd_ctl_elem_value *ucontrol)
12267 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12268 struct alc_spec *spec = codec->spec;
12269 const struct hda_input_mux *imux = spec->input_mux;
12270 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
12271 static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
12272 hda_nid_t nid = capture_mixers[adc_idx];
12273 unsigned int *cur_val = &spec->cur_mux[adc_idx];
12274 unsigned int i, idx;
12276 idx = ucontrol->value.enumerated.item[0];
12277 if (idx >= imux->num_items)
12278 idx = imux->num_items - 1;
12279 if (*cur_val == idx)
12281 for (i = 0; i < imux->num_items; i++) {
12282 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
12283 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
12284 imux->items[i].index,
12293 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
12300 static struct hda_verb alc662_3ST_ch2_init[] = {
12301 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
12302 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12303 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
12304 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12311 static struct hda_verb alc662_3ST_ch6_init[] = {
12312 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12313 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12314 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
12315 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12316 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12317 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
12321 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
12322 { 2, alc662_3ST_ch2_init },
12323 { 6, alc662_3ST_ch6_init },
12329 static struct hda_verb alc662_sixstack_ch6_init[] = {
12330 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12331 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12332 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12339 static struct hda_verb alc662_sixstack_ch8_init[] = {
12340 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12341 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12342 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12346 static struct hda_channel_mode alc662_5stack_modes[2] = {
12347 { 2, alc662_sixstack_ch6_init },
12348 { 6, alc662_sixstack_ch8_init },
12351 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12352 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12355 static struct snd_kcontrol_new alc662_base_mixer[] = {
12356 /* output mixer control */
12357 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12358 HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
12359 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12360 HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12361 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12362 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12363 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12364 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12367 /*Input mixer control */
12368 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
12369 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
12370 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
12371 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
12372 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
12373 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
12374 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
12375 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
12379 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
12380 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12381 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12383 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12384 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12385 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12386 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12387 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12388 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12389 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12390 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12391 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12392 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12396 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
12397 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12398 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12399 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12400 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12401 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12402 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12403 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12404 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12405 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12406 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12407 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12408 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12409 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12410 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12411 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12412 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12413 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12414 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12415 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12419 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
12420 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12421 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12422 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12423 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
12424 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12425 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12426 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12427 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12428 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12432 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
12433 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12435 HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12436 HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12438 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
12439 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12440 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12442 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
12443 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12444 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12448 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
12450 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12451 .name = "Channel Mode",
12452 .info = alc_ch_mode_info,
12453 .get = alc_ch_mode_get,
12454 .put = alc_ch_mode_put,
12459 static struct hda_verb alc662_init_verbs[] = {
12460 /* ADC: mute amp left and right */
12461 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12462 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12463 /* Front mixer: unmute input/output amp left and right (volume = 0) */
12465 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12466 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12467 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12468 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12469 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12471 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12472 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12473 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12474 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12475 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12476 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12478 /* Front Pin: output 0 (0x0c) */
12479 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12480 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12482 /* Rear Pin: output 1 (0x0d) */
12483 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12484 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12486 /* CLFE Pin: output 2 (0x0e) */
12487 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12488 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12490 /* Mic (rear) pin: input vref at 80% */
12491 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12492 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12493 /* Front Mic pin: input vref at 80% */
12494 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12495 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12496 /* Line In pin: input */
12497 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12498 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12499 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12500 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12501 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12502 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12503 /* CD pin widget for input */
12504 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12506 /* FIXME: use matrix-type input source selection */
12507 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12509 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12510 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12511 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12512 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12514 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12515 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12516 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12517 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12521 static struct hda_verb alc662_sue_init_verbs[] = {
12522 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
12523 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
12527 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
12528 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12529 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12534 * generic initialization of ADC, input mixers and output mixers
12536 static struct hda_verb alc662_auto_init_verbs[] = {
12538 * Unmute ADC and set the default input to mic-in
12540 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12541 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12543 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12545 * Note: PASD motherboards uses the Line In 2 as the input for front
12546 * panel mic (mic 2)
12548 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12549 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12550 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12551 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12552 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12553 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12556 * Set up output mixers (0x0c - 0x0f)
12558 /* set vol=0 to output mixers */
12559 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12560 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12561 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12563 /* set up input amps for analog loopback */
12564 /* Amp Indices: DAC = 0, mixer = 1 */
12565 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12566 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12567 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12568 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12569 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12570 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12573 /* FIXME: use matrix-type input source selection */
12574 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12576 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12577 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12581 /* capture mixer elements */
12582 static struct snd_kcontrol_new alc662_capture_mixer[] = {
12583 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12584 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12586 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12587 /* The multiple "Capture Source" controls confuse alsamixer
12588 * So call somewhat different..
12589 * FIXME: the controls appear in the "playback" view!
12591 /* .name = "Capture Source", */
12592 .name = "Input Source",
12594 .info = alc662_mux_enum_info,
12595 .get = alc662_mux_enum_get,
12596 .put = alc662_mux_enum_put,
12601 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
12603 unsigned int present;
12604 unsigned char bits;
12606 present = snd_hda_codec_read(codec, 0x14, 0,
12607 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12608 bits = present ? HDA_AMP_MUTE : 0;
12609 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12610 HDA_AMP_MUTE, bits);
12613 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
12615 unsigned int present;
12616 unsigned char bits;
12618 present = snd_hda_codec_read(codec, 0x1b, 0,
12619 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12620 bits = present ? HDA_AMP_MUTE : 0;
12621 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12622 HDA_AMP_MUTE, bits);
12623 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12624 HDA_AMP_MUTE, bits);
12627 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
12630 if ((res >> 26) == ALC880_HP_EVENT)
12631 alc662_lenovo_101e_all_automute(codec);
12632 if ((res >> 26) == ALC880_FRONT_EVENT)
12633 alc662_lenovo_101e_ispeaker_automute(codec);
12636 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
12638 unsigned int present;
12640 present = snd_hda_codec_read(codec, 0x18, 0,
12641 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12642 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12643 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12644 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12645 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12646 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12647 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12648 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12649 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12652 /* unsolicited event for HP jack sensing */
12653 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
12656 if ((res >> 26) == ALC880_HP_EVENT)
12657 alc262_hippo1_automute( codec );
12659 if ((res >> 26) == ALC880_MIC_EVENT)
12660 alc662_eeepc_mic_automute(codec);
12663 static void alc662_eeepc_inithook(struct hda_codec *codec)
12665 alc262_hippo1_automute( codec );
12666 alc662_eeepc_mic_automute(codec);
12669 #ifdef CONFIG_SND_HDA_POWER_SAVE
12670 #define alc662_loopbacks alc880_loopbacks
12674 /* pcm configuration: identiacal with ALC880 */
12675 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
12676 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
12677 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
12678 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
12681 * configuration and preset
12683 static const char *alc662_models[ALC662_MODEL_LAST] = {
12684 [ALC662_3ST_2ch_DIG] = "3stack-dig",
12685 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
12686 [ALC662_3ST_6ch] = "3stack-6ch",
12687 [ALC662_5ST_DIG] = "6stack-dig",
12688 [ALC662_LENOVO_101E] = "lenovo-101e",
12689 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
12690 [ALC662_AUTO] = "auto",
12693 static struct snd_pci_quirk alc662_cfg_tbl[] = {
12694 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
12695 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
12699 static struct alc_config_preset alc662_presets[] = {
12700 [ALC662_3ST_2ch_DIG] = {
12701 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
12702 .init_verbs = { alc662_init_verbs },
12703 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12704 .dac_nids = alc662_dac_nids,
12705 .dig_out_nid = ALC662_DIGOUT_NID,
12706 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12707 .adc_nids = alc662_adc_nids,
12708 .dig_in_nid = ALC662_DIGIN_NID,
12709 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12710 .channel_mode = alc662_3ST_2ch_modes,
12711 .input_mux = &alc662_capture_source,
12713 [ALC662_3ST_6ch_DIG] = {
12714 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12715 alc662_capture_mixer },
12716 .init_verbs = { alc662_init_verbs },
12717 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12718 .dac_nids = alc662_dac_nids,
12719 .dig_out_nid = ALC662_DIGOUT_NID,
12720 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12721 .adc_nids = alc662_adc_nids,
12722 .dig_in_nid = ALC662_DIGIN_NID,
12723 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12724 .channel_mode = alc662_3ST_6ch_modes,
12726 .input_mux = &alc662_capture_source,
12728 [ALC662_3ST_6ch] = {
12729 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12730 alc662_capture_mixer },
12731 .init_verbs = { alc662_init_verbs },
12732 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12733 .dac_nids = alc662_dac_nids,
12734 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12735 .adc_nids = alc662_adc_nids,
12736 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12737 .channel_mode = alc662_3ST_6ch_modes,
12739 .input_mux = &alc662_capture_source,
12741 [ALC662_5ST_DIG] = {
12742 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
12743 alc662_capture_mixer },
12744 .init_verbs = { alc662_init_verbs },
12745 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12746 .dac_nids = alc662_dac_nids,
12747 .dig_out_nid = ALC662_DIGOUT_NID,
12748 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12749 .adc_nids = alc662_adc_nids,
12750 .dig_in_nid = ALC662_DIGIN_NID,
12751 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
12752 .channel_mode = alc662_5stack_modes,
12753 .input_mux = &alc662_capture_source,
12755 [ALC662_LENOVO_101E] = {
12756 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
12757 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
12758 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12759 .dac_nids = alc662_dac_nids,
12760 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12761 .adc_nids = alc662_adc_nids,
12762 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12763 .channel_mode = alc662_3ST_2ch_modes,
12764 .input_mux = &alc662_lenovo_101e_capture_source,
12765 .unsol_event = alc662_lenovo_101e_unsol_event,
12766 .init_hook = alc662_lenovo_101e_all_automute,
12768 [ALC662_ASUS_EEEPC_P701] = {
12769 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
12770 .init_verbs = { alc662_init_verbs,
12771 alc662_eeepc_sue_init_verbs },
12772 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12773 .dac_nids = alc662_dac_nids,
12774 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12775 .adc_nids = alc662_adc_nids,
12776 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12777 .channel_mode = alc662_3ST_2ch_modes,
12778 .input_mux = &alc662_eeepc_capture_source,
12779 .unsol_event = alc662_eeepc_unsol_event,
12780 .init_hook = alc662_eeepc_inithook,
12787 * BIOS auto configuration
12790 /* add playback controls from the parsed DAC table */
12791 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
12792 const struct auto_pin_cfg *cfg)
12795 static const char *chname[4] = {
12796 "Front", "Surround", NULL /*CLFE*/, "Side"
12801 for (i = 0; i < cfg->line_outs; i++) {
12802 if (!spec->multiout.dac_nids[i])
12804 nid = alc880_idx_to_dac(i);
12807 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12808 "Center Playback Volume",
12809 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12813 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12814 "LFE Playback Volume",
12815 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12819 err = add_control(spec, ALC_CTL_BIND_MUTE,
12820 "Center Playback Switch",
12821 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
12825 err = add_control(spec, ALC_CTL_BIND_MUTE,
12826 "LFE Playback Switch",
12827 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
12832 sprintf(name, "%s Playback Volume", chname[i]);
12833 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12834 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12838 sprintf(name, "%s Playback Switch", chname[i]);
12839 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12840 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
12849 /* add playback controls for speaker and HP outputs */
12850 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
12860 if (alc880_is_fixed_pin(pin)) {
12861 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12862 /* printk("DAC nid=%x\n",nid); */
12863 /* specify the DAC as the extra output */
12864 if (!spec->multiout.hp_nid)
12865 spec->multiout.hp_nid = nid;
12867 spec->multiout.extra_out_nid[0] = nid;
12868 /* control HP volume/switch on the output mixer amp */
12869 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12870 sprintf(name, "%s Playback Volume", pfx);
12871 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12872 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12875 sprintf(name, "%s Playback Switch", pfx);
12876 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12877 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
12880 } else if (alc880_is_multi_pin(pin)) {
12881 /* set manual connection */
12882 /* we have only a switch on HP-out PIN */
12883 sprintf(name, "%s Playback Switch", pfx);
12884 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12885 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12892 /* create playback/capture controls for input pins */
12893 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
12894 const struct auto_pin_cfg *cfg)
12896 struct hda_input_mux *imux = &spec->private_imux;
12899 for (i = 0; i < AUTO_PIN_LAST; i++) {
12900 if (alc880_is_input_pin(cfg->input_pins[i])) {
12901 idx = alc880_input_pin_idx(cfg->input_pins[i]);
12902 err = new_analog_input(spec, cfg->input_pins[i],
12903 auto_pin_cfg_labels[i],
12907 imux->items[imux->num_items].label =
12908 auto_pin_cfg_labels[i];
12909 imux->items[imux->num_items].index =
12910 alc880_input_pin_idx(cfg->input_pins[i]);
12917 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
12918 hda_nid_t nid, int pin_type,
12921 /* set as output */
12922 snd_hda_codec_write(codec, nid, 0,
12923 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
12924 snd_hda_codec_write(codec, nid, 0,
12925 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
12926 /* need the manual connection? */
12927 if (alc880_is_multi_pin(nid)) {
12928 struct alc_spec *spec = codec->spec;
12929 int idx = alc880_multi_pin_idx(nid);
12930 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
12931 AC_VERB_SET_CONNECT_SEL,
12932 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
12936 static void alc662_auto_init_multi_out(struct hda_codec *codec)
12938 struct alc_spec *spec = codec->spec;
12941 for (i = 0; i <= HDA_SIDE; i++) {
12942 hda_nid_t nid = spec->autocfg.line_out_pins[i];
12943 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12945 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
12950 static void alc662_auto_init_hp_out(struct hda_codec *codec)
12952 struct alc_spec *spec = codec->spec;
12955 pin = spec->autocfg.hp_pins[0];
12956 if (pin) /* connect to front */
12958 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
12961 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
12962 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
12964 static void alc662_auto_init_analog_input(struct hda_codec *codec)
12966 struct alc_spec *spec = codec->spec;
12969 for (i = 0; i < AUTO_PIN_LAST; i++) {
12970 hda_nid_t nid = spec->autocfg.input_pins[i];
12971 if (alc662_is_input_pin(nid)) {
12972 snd_hda_codec_write(codec, nid, 0,
12973 AC_VERB_SET_PIN_WIDGET_CONTROL,
12974 (i <= AUTO_PIN_FRONT_MIC ?
12975 PIN_VREF80 : PIN_IN));
12976 if (nid != ALC662_PIN_CD_NID)
12977 snd_hda_codec_write(codec, nid, 0,
12978 AC_VERB_SET_AMP_GAIN_MUTE,
12984 static int alc662_parse_auto_config(struct hda_codec *codec)
12986 struct alc_spec *spec = codec->spec;
12988 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
12990 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12994 if (!spec->autocfg.line_outs)
12995 return 0; /* can't find valid BIOS pin config */
12997 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13000 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
13003 err = alc662_auto_create_extra_out(spec,
13004 spec->autocfg.speaker_pins[0],
13008 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
13012 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
13016 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13018 if (spec->autocfg.dig_out_pin)
13019 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
13021 if (spec->kctl_alloc)
13022 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13024 spec->num_mux_defs = 1;
13025 spec->input_mux = &spec->private_imux;
13027 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
13028 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
13029 spec->num_mixers++;
13033 /* additional initialization for auto-configuration model */
13034 static void alc662_auto_init(struct hda_codec *codec)
13036 alc662_auto_init_multi_out(codec);
13037 alc662_auto_init_hp_out(codec);
13038 alc662_auto_init_analog_input(codec);
13041 static int patch_alc662(struct hda_codec *codec)
13043 struct alc_spec *spec;
13044 int err, board_config;
13046 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13050 codec->spec = spec;
13052 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
13055 if (board_config < 0) {
13056 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
13057 "trying auto-probe from BIOS...\n");
13058 board_config = ALC662_AUTO;
13061 if (board_config == ALC662_AUTO) {
13062 /* automatic parse from the BIOS config */
13063 err = alc662_parse_auto_config(codec);
13069 "hda_codec: Cannot set up configuration "
13070 "from BIOS. Using base mode...\n");
13071 board_config = ALC662_3ST_2ch_DIG;
13075 if (board_config != ALC662_AUTO)
13076 setup_preset(spec, &alc662_presets[board_config]);
13078 spec->stream_name_analog = "ALC662 Analog";
13079 spec->stream_analog_playback = &alc662_pcm_analog_playback;
13080 spec->stream_analog_capture = &alc662_pcm_analog_capture;
13082 spec->stream_name_digital = "ALC662 Digital";
13083 spec->stream_digital_playback = &alc662_pcm_digital_playback;
13084 spec->stream_digital_capture = &alc662_pcm_digital_capture;
13086 if (!spec->adc_nids && spec->input_mux) {
13087 spec->adc_nids = alc662_adc_nids;
13088 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
13091 codec->patch_ops = alc_patch_ops;
13092 if (board_config == ALC662_AUTO)
13093 spec->init_hook = alc662_auto_init;
13094 #ifdef CONFIG_SND_HDA_POWER_SAVE
13095 if (!spec->loopback.amplist)
13096 spec->loopback.amplist = alc662_loopbacks;
13105 struct hda_codec_preset snd_hda_preset_realtek[] = {
13106 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
13107 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
13108 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
13109 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
13110 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
13111 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
13112 .patch = patch_alc861 },
13113 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
13114 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
13115 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
13116 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
13117 .patch = patch_alc883 },
13118 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
13119 .patch = patch_alc662 },
13120 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
13121 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
13122 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
13123 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
13124 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
13125 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
13126 {} /* terminator */