2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include "hda_codec.h"
32 #include "hda_local.h"
34 #define ALC880_FRONT_EVENT 0x01
35 #define ALC880_DCVOL_EVENT 0x02
36 #define ALC880_HP_EVENT 0x04
37 #define ALC880_MIC_EVENT 0x08
39 /* ALC880 board config type */
62 #ifdef CONFIG_SND_DEBUG
66 ALC880_MODEL_LAST /* last tag */
78 #ifdef CONFIG_SND_DEBUG
82 ALC260_MODEL_LAST /* last tag */
92 ALC262_HP_BPC_D7000_WL,
93 ALC262_HP_BPC_D7000_WF,
100 ALC262_MODEL_LAST /* last tag */
108 #ifdef CONFIG_SND_DEBUG
112 ALC268_MODEL_LAST /* last tag */
119 ALC269_MODEL_LAST /* last tag */
136 /* ALC861-VD models */
157 ALC662_ASUS_EEEPC_P701,
185 ALC883_TARGA_2ch_DIG,
191 ALC883_LENOVO_101E_2ch,
192 ALC883_LENOVO_NB0763,
193 ALC888_LENOVO_MS7195_DIG,
203 #define GPIO_MASK 0x03
206 /* codec parameterization */
207 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
208 unsigned int num_mixers;
210 const struct hda_verb *init_verbs[5]; /* initialization verbs
214 unsigned int num_init_verbs;
216 char *stream_name_analog; /* analog PCM stream */
217 struct hda_pcm_stream *stream_analog_playback;
218 struct hda_pcm_stream *stream_analog_capture;
220 char *stream_name_digital; /* digital PCM stream */
221 struct hda_pcm_stream *stream_digital_playback;
222 struct hda_pcm_stream *stream_digital_capture;
225 struct hda_multi_out multiout; /* playback set-up
226 * max_channels, dacs must be set
227 * dig_out_nid and hp_nid are optional
231 unsigned int num_adc_nids;
233 hda_nid_t dig_in_nid; /* digital-in NID; optional */
236 unsigned int num_mux_defs;
237 const struct hda_input_mux *input_mux;
238 unsigned int cur_mux[3];
241 const struct hda_channel_mode *channel_mode;
242 int num_channel_mode;
245 /* PCM information */
246 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
248 /* dynamic controls, init_verbs and input_mux */
249 struct auto_pin_cfg autocfg;
250 unsigned int num_kctl_alloc, num_kctl_used;
251 struct snd_kcontrol_new *kctl_alloc;
252 struct hda_input_mux private_imux;
253 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
256 void (*init_hook)(struct hda_codec *codec);
257 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
259 /* for pin sensing */
260 unsigned int sense_updated: 1;
261 unsigned int jack_present: 1;
263 #ifdef CONFIG_SND_HDA_POWER_SAVE
264 struct hda_loopback_check loopback;
269 * configuration template - to be copied to the spec instance
271 struct alc_config_preset {
272 struct snd_kcontrol_new *mixers[5]; /* should be identical size
275 const struct hda_verb *init_verbs[5];
276 unsigned int num_dacs;
278 hda_nid_t dig_out_nid; /* optional */
279 hda_nid_t hp_nid; /* optional */
280 unsigned int num_adc_nids;
282 hda_nid_t dig_in_nid;
283 unsigned int num_channel_mode;
284 const struct hda_channel_mode *channel_mode;
286 unsigned int num_mux_defs;
287 const struct hda_input_mux *input_mux;
288 void (*unsol_event)(struct hda_codec *, unsigned int);
289 void (*init_hook)(struct hda_codec *);
290 #ifdef CONFIG_SND_HDA_POWER_SAVE
291 struct hda_amp_list *loopbacks;
299 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
300 struct snd_ctl_elem_info *uinfo)
302 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
303 struct alc_spec *spec = codec->spec;
304 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
305 if (mux_idx >= spec->num_mux_defs)
307 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
310 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
311 struct snd_ctl_elem_value *ucontrol)
313 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
314 struct alc_spec *spec = codec->spec;
315 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
317 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
321 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
322 struct snd_ctl_elem_value *ucontrol)
324 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
325 struct alc_spec *spec = codec->spec;
326 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
327 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
328 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
329 spec->adc_nids[adc_idx],
330 &spec->cur_mux[adc_idx]);
335 * channel mode setting
337 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
338 struct snd_ctl_elem_info *uinfo)
340 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
341 struct alc_spec *spec = codec->spec;
342 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
343 spec->num_channel_mode);
346 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
347 struct snd_ctl_elem_value *ucontrol)
349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
350 struct alc_spec *spec = codec->spec;
351 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
352 spec->num_channel_mode,
353 spec->multiout.max_channels);
356 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
357 struct snd_ctl_elem_value *ucontrol)
359 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
360 struct alc_spec *spec = codec->spec;
361 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
362 spec->num_channel_mode,
363 &spec->multiout.max_channels);
364 if (err >= 0 && spec->need_dac_fix)
365 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
370 * Control the mode of pin widget settings via the mixer. "pc" is used
371 * instead of "%" to avoid consequences of accidently treating the % as
372 * being part of a format specifier. Maximum allowed length of a value is
373 * 63 characters plus NULL terminator.
375 * Note: some retasking pin complexes seem to ignore requests for input
376 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
377 * are requested. Therefore order this list so that this behaviour will not
378 * cause problems when mixer clients move through the enum sequentially.
379 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
382 static char *alc_pin_mode_names[] = {
383 "Mic 50pc bias", "Mic 80pc bias",
384 "Line in", "Line out", "Headphone out",
386 static unsigned char alc_pin_mode_values[] = {
387 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
389 /* The control can present all 5 options, or it can limit the options based
390 * in the pin being assumed to be exclusively an input or an output pin. In
391 * addition, "input" pins may or may not process the mic bias option
392 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
393 * accept requests for bias as of chip versions up to March 2006) and/or
394 * wiring in the computer.
396 #define ALC_PIN_DIR_IN 0x00
397 #define ALC_PIN_DIR_OUT 0x01
398 #define ALC_PIN_DIR_INOUT 0x02
399 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
400 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
402 /* Info about the pin modes supported by the different pin direction modes.
403 * For each direction the minimum and maximum values are given.
405 static signed char alc_pin_mode_dir_info[5][2] = {
406 { 0, 2 }, /* ALC_PIN_DIR_IN */
407 { 3, 4 }, /* ALC_PIN_DIR_OUT */
408 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
409 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
410 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
412 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
413 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
414 #define alc_pin_mode_n_items(_dir) \
415 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
417 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
418 struct snd_ctl_elem_info *uinfo)
420 unsigned int item_num = uinfo->value.enumerated.item;
421 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
423 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
425 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
427 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
428 item_num = alc_pin_mode_min(dir);
429 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
433 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
434 struct snd_ctl_elem_value *ucontrol)
437 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
438 hda_nid_t nid = kcontrol->private_value & 0xffff;
439 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
440 long *valp = ucontrol->value.integer.value;
441 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
442 AC_VERB_GET_PIN_WIDGET_CONTROL,
445 /* Find enumerated value for current pinctl setting */
446 i = alc_pin_mode_min(dir);
447 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
449 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
453 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
454 struct snd_ctl_elem_value *ucontrol)
457 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
458 hda_nid_t nid = kcontrol->private_value & 0xffff;
459 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
460 long val = *ucontrol->value.integer.value;
461 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
462 AC_VERB_GET_PIN_WIDGET_CONTROL,
465 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
466 val = alc_pin_mode_min(dir);
468 change = pinctl != alc_pin_mode_values[val];
470 /* Set pin mode to that requested */
471 snd_hda_codec_write_cache(codec, nid, 0,
472 AC_VERB_SET_PIN_WIDGET_CONTROL,
473 alc_pin_mode_values[val]);
475 /* Also enable the retasking pin's input/output as required
476 * for the requested pin mode. Enum values of 2 or less are
479 * Dynamically switching the input/output buffers probably
480 * reduces noise slightly (particularly on input) so we'll
481 * do it. However, having both input and output buffers
482 * enabled simultaneously doesn't seem to be problematic if
483 * this turns out to be necessary in the future.
486 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
487 HDA_AMP_MUTE, HDA_AMP_MUTE);
488 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
491 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
492 HDA_AMP_MUTE, HDA_AMP_MUTE);
493 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
500 #define ALC_PIN_MODE(xname, nid, dir) \
501 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
502 .info = alc_pin_mode_info, \
503 .get = alc_pin_mode_get, \
504 .put = alc_pin_mode_put, \
505 .private_value = nid | (dir<<16) }
507 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
508 * together using a mask with more than one bit set. This control is
509 * currently used only by the ALC260 test model. At this stage they are not
510 * needed for any "production" models.
512 #ifdef CONFIG_SND_DEBUG
513 #define alc_gpio_data_info snd_ctl_boolean_mono_info
515 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
516 struct snd_ctl_elem_value *ucontrol)
518 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
519 hda_nid_t nid = kcontrol->private_value & 0xffff;
520 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
521 long *valp = ucontrol->value.integer.value;
522 unsigned int val = snd_hda_codec_read(codec, nid, 0,
523 AC_VERB_GET_GPIO_DATA, 0x00);
525 *valp = (val & mask) != 0;
528 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
529 struct snd_ctl_elem_value *ucontrol)
532 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
533 hda_nid_t nid = kcontrol->private_value & 0xffff;
534 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
535 long val = *ucontrol->value.integer.value;
536 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
537 AC_VERB_GET_GPIO_DATA,
540 /* Set/unset the masked GPIO bit(s) as needed */
541 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
546 snd_hda_codec_write_cache(codec, nid, 0,
547 AC_VERB_SET_GPIO_DATA, gpio_data);
551 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
552 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
553 .info = alc_gpio_data_info, \
554 .get = alc_gpio_data_get, \
555 .put = alc_gpio_data_put, \
556 .private_value = nid | (mask<<16) }
557 #endif /* CONFIG_SND_DEBUG */
559 /* A switch control to allow the enabling of the digital IO pins on the
560 * ALC260. This is incredibly simplistic; the intention of this control is
561 * to provide something in the test model allowing digital outputs to be
562 * identified if present. If models are found which can utilise these
563 * outputs a more complete mixer control can be devised for those models if
566 #ifdef CONFIG_SND_DEBUG
567 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
569 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
570 struct snd_ctl_elem_value *ucontrol)
572 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
573 hda_nid_t nid = kcontrol->private_value & 0xffff;
574 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
575 long *valp = ucontrol->value.integer.value;
576 unsigned int val = snd_hda_codec_read(codec, nid, 0,
577 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
579 *valp = (val & mask) != 0;
582 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
583 struct snd_ctl_elem_value *ucontrol)
586 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
587 hda_nid_t nid = kcontrol->private_value & 0xffff;
588 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
589 long val = *ucontrol->value.integer.value;
590 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
591 AC_VERB_GET_DIGI_CONVERT_1,
594 /* Set/unset the masked control bit(s) as needed */
595 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
600 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
605 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
606 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
607 .info = alc_spdif_ctrl_info, \
608 .get = alc_spdif_ctrl_get, \
609 .put = alc_spdif_ctrl_put, \
610 .private_value = nid | (mask<<16) }
611 #endif /* CONFIG_SND_DEBUG */
613 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
614 * Again, this is only used in the ALC26x test models to help identify when
615 * the EAPD line must be asserted for features to work.
617 #ifdef CONFIG_SND_DEBUG
618 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
620 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
621 struct snd_ctl_elem_value *ucontrol)
623 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
624 hda_nid_t nid = kcontrol->private_value & 0xffff;
625 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
626 long *valp = ucontrol->value.integer.value;
627 unsigned int val = snd_hda_codec_read(codec, nid, 0,
628 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
630 *valp = (val & mask) != 0;
634 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
635 struct snd_ctl_elem_value *ucontrol)
638 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
639 hda_nid_t nid = kcontrol->private_value & 0xffff;
640 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
641 long val = *ucontrol->value.integer.value;
642 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
643 AC_VERB_GET_EAPD_BTLENABLE,
646 /* Set/unset the masked control bit(s) as needed */
647 change = (!val ? 0 : mask) != (ctrl_data & mask);
652 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
658 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
659 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
660 .info = alc_eapd_ctrl_info, \
661 .get = alc_eapd_ctrl_get, \
662 .put = alc_eapd_ctrl_put, \
663 .private_value = nid | (mask<<16) }
664 #endif /* CONFIG_SND_DEBUG */
667 * set up from the preset table
669 static void setup_preset(struct alc_spec *spec,
670 const struct alc_config_preset *preset)
674 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
675 spec->mixers[spec->num_mixers++] = preset->mixers[i];
676 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
678 spec->init_verbs[spec->num_init_verbs++] =
679 preset->init_verbs[i];
681 spec->channel_mode = preset->channel_mode;
682 spec->num_channel_mode = preset->num_channel_mode;
683 spec->need_dac_fix = preset->need_dac_fix;
685 spec->multiout.max_channels = spec->channel_mode[0].channels;
687 spec->multiout.num_dacs = preset->num_dacs;
688 spec->multiout.dac_nids = preset->dac_nids;
689 spec->multiout.dig_out_nid = preset->dig_out_nid;
690 spec->multiout.hp_nid = preset->hp_nid;
692 spec->num_mux_defs = preset->num_mux_defs;
693 if (!spec->num_mux_defs)
694 spec->num_mux_defs = 1;
695 spec->input_mux = preset->input_mux;
697 spec->num_adc_nids = preset->num_adc_nids;
698 spec->adc_nids = preset->adc_nids;
699 spec->dig_in_nid = preset->dig_in_nid;
701 spec->unsol_event = preset->unsol_event;
702 spec->init_hook = preset->init_hook;
703 #ifdef CONFIG_SND_HDA_POWER_SAVE
704 spec->loopback.amplist = preset->loopbacks;
708 /* Enable GPIO mask and set output */
709 static struct hda_verb alc_gpio1_init_verbs[] = {
710 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
711 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
712 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
716 static struct hda_verb alc_gpio2_init_verbs[] = {
717 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
718 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
719 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
723 static struct hda_verb alc_gpio3_init_verbs[] = {
724 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
725 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
726 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
730 static void alc_sku_automute(struct hda_codec *codec)
732 struct alc_spec *spec = codec->spec;
734 unsigned int present;
735 unsigned int hp_nid = spec->autocfg.hp_pins[0];
736 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
738 /* need to execute and sync at first */
739 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
740 present = snd_hda_codec_read(codec, hp_nid, 0,
741 AC_VERB_GET_PIN_SENSE, 0);
742 spec->jack_present = (present & 0x80000000) != 0;
743 if (spec->jack_present) {
744 /* mute internal speaker */
745 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
746 HDA_AMP_MUTE, HDA_AMP_MUTE);
748 /* unmute internal speaker if necessary */
749 mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0);
750 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
755 /* unsolicited event for HP jack sensing */
756 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
758 if (codec->vendor_id == 0x10ec0880)
762 if (res != ALC880_HP_EVENT)
765 alc_sku_automute(codec);
768 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
769 * 31 ~ 16 : Manufacture ID
771 * 7 ~ 0 : Assembly ID
772 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
774 static void alc_subsystem_id(struct hda_codec *codec,
775 unsigned int porta, unsigned int porte,
778 unsigned int ass, tmp, i;
780 struct alc_spec *spec = codec->spec;
782 ass = codec->subsystem_id & 0xffff;
783 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
787 * 31~30 : port conetcivity
790 * 19~16 : Check sum (15:1)
795 if (codec->vendor_id == 0x10ec0260)
797 ass = snd_hda_codec_read(codec, nid, 0,
798 AC_VERB_GET_CONFIG_DEFAULT, 0);
799 if (!(ass & 1) && !(ass & 0x100000))
801 if ((ass >> 30) != 1) /* no physical connection */
806 for (i = 1; i < 16; i++) {
810 if (((ass >> 16) & 0xf) != tmp)
816 * 2 : 0 --> Desktop, 1 --> Laptop
817 * 3~5 : External Amplifier control
820 tmp = (ass & 0x38) >> 3; /* external Amp control */
823 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
826 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
829 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
831 case 5: /* set EAPD output high */
832 switch (codec->vendor_id) {
834 snd_hda_codec_write(codec, 0x0f, 0,
835 AC_VERB_SET_EAPD_BTLENABLE, 2);
836 snd_hda_codec_write(codec, 0x10, 0,
837 AC_VERB_SET_EAPD_BTLENABLE, 2);
845 snd_hda_codec_write(codec, 0x14, 0,
846 AC_VERB_SET_EAPD_BTLENABLE, 2);
847 snd_hda_codec_write(codec, 0x15, 0,
848 AC_VERB_SET_EAPD_BTLENABLE, 2);
851 switch (codec->vendor_id) {
853 snd_hda_codec_write(codec, 0x1a, 0,
854 AC_VERB_SET_COEF_INDEX, 7);
855 tmp = snd_hda_codec_read(codec, 0x1a, 0,
856 AC_VERB_GET_PROC_COEF, 0);
857 snd_hda_codec_write(codec, 0x1a, 0,
858 AC_VERB_SET_COEF_INDEX, 7);
859 snd_hda_codec_write(codec, 0x1a, 0,
860 AC_VERB_SET_PROC_COEF,
869 snd_hda_codec_write(codec, 0x20, 0,
870 AC_VERB_SET_COEF_INDEX, 7);
871 tmp = snd_hda_codec_read(codec, 0x20, 0,
872 AC_VERB_GET_PROC_COEF, 0);
873 snd_hda_codec_write(codec, 0x20, 0,
874 AC_VERB_SET_COEF_INDEX, 7);
875 snd_hda_codec_write(codec, 0x20, 0,
876 AC_VERB_SET_PROC_COEF,
881 snd_hda_codec_write(codec, 0x20, 0,
882 AC_VERB_SET_COEF_INDEX, 7);
883 tmp = snd_hda_codec_read(codec, 0x20, 0,
884 AC_VERB_GET_PROC_COEF, 0);
885 snd_hda_codec_write(codec, 0x20, 0,
886 AC_VERB_SET_COEF_INDEX, 7);
887 snd_hda_codec_write(codec, 0x20, 0,
888 AC_VERB_SET_PROC_COEF,
896 /* is laptop and enable the function "Mute internal speaker
897 * when the external headphone out jack is plugged"
899 if (!(ass & 0x4) || !(ass & 0x8000))
902 * 10~8 : Jack location
903 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
905 * 15 : 1 --> enable the function "Mute internal speaker
906 * when the external headphone out jack is plugged"
908 if (!spec->autocfg.speaker_pins[0]) {
909 if (spec->multiout.dac_nids[0])
910 spec->autocfg.speaker_pins[0] =
911 spec->multiout.dac_nids[0];
916 if (!spec->autocfg.hp_pins[0]) {
917 tmp = (ass >> 11) & 0x3; /* HP to chassis */
919 spec->autocfg.hp_pins[0] = porta;
921 spec->autocfg.hp_pins[0] = porte;
923 spec->autocfg.hp_pins[0] = portd;
928 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
929 AC_VERB_SET_UNSOLICITED_ENABLE,
930 AC_USRSP_EN | ALC880_HP_EVENT);
931 spec->unsol_event = alc_sku_unsol_event;
932 spec->init_hook = alc_sku_automute;
936 * Fix-up pin default configurations
944 static void alc_fix_pincfg(struct hda_codec *codec,
945 const struct snd_pci_quirk *quirk,
946 const struct alc_pincfg **pinfix)
948 const struct alc_pincfg *cfg;
950 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
954 cfg = pinfix[quirk->value];
955 for (; cfg->nid; cfg++) {
958 for (i = 0; i < 4; i++) {
959 snd_hda_codec_write(codec, cfg->nid, 0,
960 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
968 * ALC880 3-stack model
970 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
971 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
972 * F-Mic = 0x1b, HP = 0x19
975 static hda_nid_t alc880_dac_nids[4] = {
976 /* front, rear, clfe, rear_surr */
977 0x02, 0x05, 0x04, 0x03
980 static hda_nid_t alc880_adc_nids[3] = {
985 /* The datasheet says the node 0x07 is connected from inputs,
986 * but it shows zero connection in the real implementation on some devices.
987 * Note: this is a 915GAV bug, fixed on 915GLV
989 static hda_nid_t alc880_adc_nids_alt[2] = {
994 #define ALC880_DIGOUT_NID 0x06
995 #define ALC880_DIGIN_NID 0x0a
997 static struct hda_input_mux alc880_capture_source = {
1001 { "Front Mic", 0x3 },
1007 /* channel source setting (2/6 channel selection for 3-stack) */
1009 static struct hda_verb alc880_threestack_ch2_init[] = {
1010 /* set line-in to input, mute it */
1011 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1012 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1013 /* set mic-in to input vref 80%, mute it */
1014 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1015 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1020 static struct hda_verb alc880_threestack_ch6_init[] = {
1021 /* set line-in to output, unmute it */
1022 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1023 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1024 /* set mic-in to output, unmute it */
1025 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1026 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1030 static struct hda_channel_mode alc880_threestack_modes[2] = {
1031 { 2, alc880_threestack_ch2_init },
1032 { 6, alc880_threestack_ch6_init },
1035 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1036 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1037 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1038 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1039 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1040 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1041 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1042 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1043 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1044 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1045 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1046 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1047 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1048 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1049 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1050 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1051 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1052 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1053 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1054 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1056 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1057 .name = "Channel Mode",
1058 .info = alc_ch_mode_info,
1059 .get = alc_ch_mode_get,
1060 .put = alc_ch_mode_put,
1065 /* capture mixer elements */
1066 static struct snd_kcontrol_new alc880_capture_mixer[] = {
1067 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1068 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1069 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1070 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1071 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1072 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1074 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1075 /* The multiple "Capture Source" controls confuse alsamixer
1076 * So call somewhat different..
1077 * FIXME: the controls appear in the "playback" view!
1079 /* .name = "Capture Source", */
1080 .name = "Input Source",
1082 .info = alc_mux_enum_info,
1083 .get = alc_mux_enum_get,
1084 .put = alc_mux_enum_put,
1089 /* capture mixer elements (in case NID 0x07 not available) */
1090 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1091 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1092 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1093 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1094 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1096 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1097 /* The multiple "Capture Source" controls confuse alsamixer
1098 * So call somewhat different..
1099 * FIXME: the controls appear in the "playback" view!
1101 /* .name = "Capture Source", */
1102 .name = "Input Source",
1104 .info = alc_mux_enum_info,
1105 .get = alc_mux_enum_get,
1106 .put = alc_mux_enum_put,
1114 * ALC880 5-stack model
1116 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1118 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1119 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1122 /* additional mixers to alc880_three_stack_mixer */
1123 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1124 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1125 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1129 /* channel source setting (6/8 channel selection for 5-stack) */
1131 static struct hda_verb alc880_fivestack_ch6_init[] = {
1132 /* set line-in to input, mute it */
1133 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1134 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1139 static struct hda_verb alc880_fivestack_ch8_init[] = {
1140 /* set line-in to output, unmute it */
1141 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1142 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1146 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1147 { 6, alc880_fivestack_ch6_init },
1148 { 8, alc880_fivestack_ch8_init },
1153 * ALC880 6-stack model
1155 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1156 * Side = 0x05 (0x0f)
1157 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1158 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1161 static hda_nid_t alc880_6st_dac_nids[4] = {
1162 /* front, rear, clfe, rear_surr */
1163 0x02, 0x03, 0x04, 0x05
1166 static struct hda_input_mux alc880_6stack_capture_source = {
1170 { "Front Mic", 0x1 },
1176 /* fixed 8-channels */
1177 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1181 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1182 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1183 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1184 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1185 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1186 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1187 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1188 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1189 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1190 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1191 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1192 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1193 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1194 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1195 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1196 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1197 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1198 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1199 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1200 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1201 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1203 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1204 .name = "Channel Mode",
1205 .info = alc_ch_mode_info,
1206 .get = alc_ch_mode_get,
1207 .put = alc_ch_mode_put,
1216 * W810 has rear IO for:
1219 * Center/LFE (DAC 04)
1222 * The system also has a pair of internal speakers, and a headphone jack.
1223 * These are both connected to Line2 on the codec, hence to DAC 02.
1225 * There is a variable resistor to control the speaker or headphone
1226 * volume. This is a hardware-only device without a software API.
1228 * Plugging headphones in will disable the internal speakers. This is
1229 * implemented in hardware, not via the driver using jack sense. In
1230 * a similar fashion, plugging into the rear socket marked "front" will
1231 * disable both the speakers and headphones.
1233 * For input, there's a microphone jack, and an "audio in" jack.
1234 * These may not do anything useful with this driver yet, because I
1235 * haven't setup any initialization verbs for these yet...
1238 static hda_nid_t alc880_w810_dac_nids[3] = {
1239 /* front, rear/surround, clfe */
1243 /* fixed 6 channels */
1244 static struct hda_channel_mode alc880_w810_modes[1] = {
1248 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1249 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1250 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1251 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1252 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1253 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1254 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1255 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1256 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1257 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1258 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1266 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1267 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1271 static hda_nid_t alc880_z71v_dac_nids[1] = {
1274 #define ALC880_Z71V_HP_DAC 0x03
1276 /* fixed 2 channels */
1277 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1281 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1282 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1283 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1284 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1285 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1286 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1287 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1288 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1289 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1296 * ALC880 F1734 model
1298 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1299 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1302 static hda_nid_t alc880_f1734_dac_nids[1] = {
1305 #define ALC880_F1734_HP_DAC 0x02
1307 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1308 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1309 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1310 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1311 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1312 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1313 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1314 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1324 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1325 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1326 * Mic = 0x18, Line = 0x1a
1329 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1330 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1332 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1333 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1334 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1335 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1336 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1337 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1338 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1339 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1340 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1341 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1342 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1343 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1344 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1345 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1346 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1348 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1349 .name = "Channel Mode",
1350 .info = alc_ch_mode_info,
1351 .get = alc_ch_mode_get,
1352 .put = alc_ch_mode_put,
1359 * ALC880 ASUS W1V model
1361 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1362 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1363 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1366 /* additional mixers to alc880_asus_mixer */
1367 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1368 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1369 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1373 /* additional mixers to alc880_asus_mixer */
1374 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1375 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1376 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1381 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1382 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1383 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1384 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1385 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1386 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1387 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1388 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1389 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1390 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1392 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1393 /* The multiple "Capture Source" controls confuse alsamixer
1394 * So call somewhat different..
1395 * FIXME: the controls appear in the "playback" view!
1397 /* .name = "Capture Source", */
1398 .name = "Input Source",
1400 .info = alc_mux_enum_info,
1401 .get = alc_mux_enum_get,
1402 .put = alc_mux_enum_put,
1408 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1409 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1410 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1411 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1412 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1413 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1414 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1415 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1416 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1417 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1418 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1419 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1420 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1421 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1422 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1423 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1424 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1425 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1426 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1429 .name = "Channel Mode",
1430 .info = alc_ch_mode_info,
1431 .get = alc_ch_mode_get,
1432 .put = alc_ch_mode_put,
1437 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1438 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1439 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1440 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1441 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1442 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1443 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1444 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1445 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1446 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1447 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1451 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1452 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1453 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1454 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1455 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1456 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1457 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1462 * build control elements
1464 static int alc_build_controls(struct hda_codec *codec)
1466 struct alc_spec *spec = codec->spec;
1470 for (i = 0; i < spec->num_mixers; i++) {
1471 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1476 if (spec->multiout.dig_out_nid) {
1477 err = snd_hda_create_spdif_out_ctls(codec,
1478 spec->multiout.dig_out_nid);
1482 if (spec->dig_in_nid) {
1483 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1492 * initialize the codec volumes, etc
1496 * generic initialization of ADC, input mixers and output mixers
1498 static struct hda_verb alc880_volume_init_verbs[] = {
1500 * Unmute ADC0-2 and set the default input to mic-in
1502 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1504 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1505 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1506 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1507 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1509 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1511 * Note: PASD motherboards uses the Line In 2 as the input for front
1514 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1515 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1516 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1517 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1518 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1519 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1520 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1524 * Set up output mixers (0x0c - 0x0f)
1526 /* set vol=0 to output mixers */
1527 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1528 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1529 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1530 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1531 /* set up input amps for analog loopback */
1532 /* Amp Indices: DAC = 0, mixer = 1 */
1533 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1534 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1535 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1536 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1537 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1538 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1539 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1540 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1546 * 3-stack pin configuration:
1547 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1549 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1551 * preset connection lists of input pins
1552 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1554 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1555 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1556 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1559 * Set pin mode and muting
1561 /* set front pin widgets 0x14 for output */
1562 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1563 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1564 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1565 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1566 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1567 /* Mic2 (as headphone out) for HP output */
1568 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1569 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1570 /* Line In pin widget for input */
1571 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1572 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1573 /* Line2 (as front mic) pin widget for input and vref at 80% */
1574 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1575 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1576 /* CD pin widget for input */
1577 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1583 * 5-stack pin configuration:
1584 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1585 * line-in/side = 0x1a, f-mic = 0x1b
1587 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1589 * preset connection lists of input pins
1590 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1592 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1593 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1596 * Set pin mode and muting
1598 /* set pin widgets 0x14-0x17 for output */
1599 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1600 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1601 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1602 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1603 /* unmute pins for output (no gain on this amp) */
1604 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1605 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1606 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1607 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1609 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1610 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1611 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1612 /* Mic2 (as headphone out) for HP output */
1613 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1614 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1615 /* Line In pin widget for input */
1616 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1617 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1618 /* Line2 (as front mic) pin widget for input and vref at 80% */
1619 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1620 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1621 /* CD pin widget for input */
1622 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1628 * W810 pin configuration:
1629 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1631 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1632 /* hphone/speaker input selector: front DAC */
1633 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1635 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1636 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1637 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1638 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1639 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1640 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1642 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1643 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1649 * Z71V pin configuration:
1650 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1652 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1653 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1654 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1655 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1656 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1658 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1659 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1660 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1661 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1667 * 6-stack pin configuration:
1668 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1669 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1671 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1672 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1674 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1675 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1676 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1677 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1678 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1679 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1680 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1681 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1683 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1684 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1685 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1686 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1687 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1688 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1689 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1690 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1691 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1697 * Uniwill pin configuration:
1698 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1701 static struct hda_verb alc880_uniwill_init_verbs[] = {
1702 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1704 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1705 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1706 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1707 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1708 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1709 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1710 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1711 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1712 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1713 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1714 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1715 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1716 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1717 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1719 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1720 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1721 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1722 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1723 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1724 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1725 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1726 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1727 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1729 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1730 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1737 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1739 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1740 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1742 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1743 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1744 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1745 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1746 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1747 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1748 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1749 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1750 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1751 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1752 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1753 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1755 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1756 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1757 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1758 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1759 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1760 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1762 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1763 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1768 static struct hda_verb alc880_beep_init_verbs[] = {
1769 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1773 /* toggle speaker-output according to the hp-jack state */
1774 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1776 unsigned int present;
1779 present = snd_hda_codec_read(codec, 0x14, 0,
1780 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1781 bits = present ? HDA_AMP_MUTE : 0;
1782 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1783 HDA_AMP_MUTE, bits);
1784 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1785 HDA_AMP_MUTE, bits);
1788 /* auto-toggle front mic */
1789 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1791 unsigned int present;
1794 present = snd_hda_codec_read(codec, 0x18, 0,
1795 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1796 bits = present ? HDA_AMP_MUTE : 0;
1797 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1800 static void alc880_uniwill_automute(struct hda_codec *codec)
1802 alc880_uniwill_hp_automute(codec);
1803 alc880_uniwill_mic_automute(codec);
1806 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1809 /* Looks like the unsol event is incompatible with the standard
1810 * definition. 4bit tag is placed at 28 bit!
1812 switch (res >> 28) {
1813 case ALC880_HP_EVENT:
1814 alc880_uniwill_hp_automute(codec);
1816 case ALC880_MIC_EVENT:
1817 alc880_uniwill_mic_automute(codec);
1822 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1824 unsigned int present;
1827 present = snd_hda_codec_read(codec, 0x14, 0,
1828 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1829 bits = present ? HDA_AMP_MUTE : 0;
1830 snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1833 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1835 unsigned int present;
1837 present = snd_hda_codec_read(codec, 0x21, 0,
1838 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1839 present &= HDA_AMP_VOLMASK;
1840 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1841 HDA_AMP_VOLMASK, present);
1842 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1843 HDA_AMP_VOLMASK, present);
1846 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1849 /* Looks like the unsol event is incompatible with the standard
1850 * definition. 4bit tag is placed at 28 bit!
1852 if ((res >> 28) == ALC880_HP_EVENT)
1853 alc880_uniwill_p53_hp_automute(codec);
1854 if ((res >> 28) == ALC880_DCVOL_EVENT)
1855 alc880_uniwill_p53_dcvol_automute(codec);
1860 * F1734 pin configuration:
1861 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1863 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1864 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1865 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1866 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1867 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1869 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1870 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1871 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1872 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1874 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1875 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1876 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1877 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1878 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1879 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1880 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1881 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1882 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1889 * ASUS pin configuration:
1890 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1892 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1893 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1894 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1895 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1896 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1898 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1899 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1900 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1901 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1902 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1903 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1904 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1905 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1907 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1908 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1909 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1910 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1911 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1912 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1913 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1914 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1915 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1920 /* Enable GPIO mask and set output */
1921 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1922 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1924 /* Clevo m520g init */
1925 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1926 /* headphone output */
1927 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1929 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1930 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1932 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1933 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1935 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1936 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1937 /* Mic1 (rear panel) */
1938 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1939 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1940 /* Mic2 (front panel) */
1941 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1942 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1944 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1945 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1946 /* change to EAPD mode */
1947 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1948 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
1953 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1954 /* change to EAPD mode */
1955 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1956 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
1958 /* Headphone output */
1959 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1961 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1962 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1964 /* Line In pin widget for input */
1965 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1966 /* CD pin widget for input */
1967 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1968 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1969 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1971 /* change to EAPD mode */
1972 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1973 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
1979 * LG m1 express dual
1982 * Rear Line-In/Out (blue): 0x14
1983 * Build-in Mic-In: 0x15
1985 * HP-Out (green): 0x1b
1986 * Mic-In/Out (red): 0x19
1990 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1991 static hda_nid_t alc880_lg_dac_nids[3] = {
1995 /* seems analog CD is not working */
1996 static struct hda_input_mux alc880_lg_capture_source = {
2001 { "Internal Mic", 0x6 },
2005 /* 2,4,6 channel modes */
2006 static struct hda_verb alc880_lg_ch2_init[] = {
2007 /* set line-in and mic-in to input */
2008 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2009 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2013 static struct hda_verb alc880_lg_ch4_init[] = {
2014 /* set line-in to out and mic-in to input */
2015 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2016 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2020 static struct hda_verb alc880_lg_ch6_init[] = {
2021 /* set line-in and mic-in to output */
2022 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2023 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2027 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2028 { 2, alc880_lg_ch2_init },
2029 { 4, alc880_lg_ch4_init },
2030 { 6, alc880_lg_ch6_init },
2033 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2034 /* FIXME: it's not really "master" but front channels */
2035 HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2036 HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
2037 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2038 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2039 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2040 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2041 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2042 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2043 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2044 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2045 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2046 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2047 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2048 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2050 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2051 .name = "Channel Mode",
2052 .info = alc_ch_mode_info,
2053 .get = alc_ch_mode_get,
2054 .put = alc_ch_mode_put,
2059 static struct hda_verb alc880_lg_init_verbs[] = {
2060 /* set capture source to mic-in */
2061 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2062 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2063 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2064 /* mute all amp mixer inputs */
2065 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2066 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2067 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2068 /* line-in to input */
2069 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2070 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2072 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2073 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2075 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2076 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2077 /* mic-in to input */
2078 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2079 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2080 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2082 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2083 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2084 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2086 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2090 /* toggle speaker-output according to the hp-jack state */
2091 static void alc880_lg_automute(struct hda_codec *codec)
2093 unsigned int present;
2096 present = snd_hda_codec_read(codec, 0x1b, 0,
2097 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2098 bits = present ? HDA_AMP_MUTE : 0;
2099 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2100 HDA_AMP_MUTE, bits);
2103 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2105 /* Looks like the unsol event is incompatible with the standard
2106 * definition. 4bit tag is placed at 28 bit!
2108 if ((res >> 28) == 0x01)
2109 alc880_lg_automute(codec);
2118 * Built-in Mic-In: 0x19
2124 static struct hda_input_mux alc880_lg_lw_capture_source = {
2128 { "Internal Mic", 0x1 },
2133 #define alc880_lg_lw_modes alc880_threestack_modes
2135 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2136 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2137 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2138 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2139 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2140 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2141 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2142 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2143 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2144 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2145 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2146 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2147 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2148 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2149 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2151 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2152 .name = "Channel Mode",
2153 .info = alc_ch_mode_info,
2154 .get = alc_ch_mode_get,
2155 .put = alc_ch_mode_put,
2160 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2161 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2162 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2163 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2165 /* set capture source to mic-in */
2166 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2167 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2168 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2169 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2172 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2174 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2175 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2176 /* mic-in to input */
2177 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2178 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2180 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2181 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2183 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2187 /* toggle speaker-output according to the hp-jack state */
2188 static void alc880_lg_lw_automute(struct hda_codec *codec)
2190 unsigned int present;
2193 present = snd_hda_codec_read(codec, 0x1b, 0,
2194 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2195 bits = present ? HDA_AMP_MUTE : 0;
2196 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2197 HDA_AMP_MUTE, bits);
2200 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2202 /* Looks like the unsol event is incompatible with the standard
2203 * definition. 4bit tag is placed at 28 bit!
2205 if ((res >> 28) == 0x01)
2206 alc880_lg_lw_automute(codec);
2209 #ifdef CONFIG_SND_HDA_POWER_SAVE
2210 static struct hda_amp_list alc880_loopbacks[] = {
2211 { 0x0b, HDA_INPUT, 0 },
2212 { 0x0b, HDA_INPUT, 1 },
2213 { 0x0b, HDA_INPUT, 2 },
2214 { 0x0b, HDA_INPUT, 3 },
2215 { 0x0b, HDA_INPUT, 4 },
2219 static struct hda_amp_list alc880_lg_loopbacks[] = {
2220 { 0x0b, HDA_INPUT, 1 },
2221 { 0x0b, HDA_INPUT, 6 },
2222 { 0x0b, HDA_INPUT, 7 },
2231 static int alc_init(struct hda_codec *codec)
2233 struct alc_spec *spec = codec->spec;
2236 for (i = 0; i < spec->num_init_verbs; i++)
2237 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2239 if (spec->init_hook)
2240 spec->init_hook(codec);
2245 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2247 struct alc_spec *spec = codec->spec;
2249 if (spec->unsol_event)
2250 spec->unsol_event(codec, res);
2253 #ifdef CONFIG_SND_HDA_POWER_SAVE
2254 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2256 struct alc_spec *spec = codec->spec;
2257 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2262 * Analog playback callbacks
2264 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2265 struct hda_codec *codec,
2266 struct snd_pcm_substream *substream)
2268 struct alc_spec *spec = codec->spec;
2269 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2272 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2273 struct hda_codec *codec,
2274 unsigned int stream_tag,
2275 unsigned int format,
2276 struct snd_pcm_substream *substream)
2278 struct alc_spec *spec = codec->spec;
2279 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2280 stream_tag, format, substream);
2283 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2284 struct hda_codec *codec,
2285 struct snd_pcm_substream *substream)
2287 struct alc_spec *spec = codec->spec;
2288 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2294 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2295 struct hda_codec *codec,
2296 struct snd_pcm_substream *substream)
2298 struct alc_spec *spec = codec->spec;
2299 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2302 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2303 struct hda_codec *codec,
2304 unsigned int stream_tag,
2305 unsigned int format,
2306 struct snd_pcm_substream *substream)
2308 struct alc_spec *spec = codec->spec;
2309 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2310 stream_tag, format, substream);
2313 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2314 struct hda_codec *codec,
2315 struct snd_pcm_substream *substream)
2317 struct alc_spec *spec = codec->spec;
2318 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2324 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2325 struct hda_codec *codec,
2326 unsigned int stream_tag,
2327 unsigned int format,
2328 struct snd_pcm_substream *substream)
2330 struct alc_spec *spec = codec->spec;
2332 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2333 stream_tag, 0, format);
2337 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2338 struct hda_codec *codec,
2339 struct snd_pcm_substream *substream)
2341 struct alc_spec *spec = codec->spec;
2343 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2351 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2355 /* NID is set in alc_build_pcms */
2357 .open = alc880_playback_pcm_open,
2358 .prepare = alc880_playback_pcm_prepare,
2359 .cleanup = alc880_playback_pcm_cleanup
2363 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2367 /* NID is set in alc_build_pcms */
2369 .prepare = alc880_capture_pcm_prepare,
2370 .cleanup = alc880_capture_pcm_cleanup
2374 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2378 /* NID is set in alc_build_pcms */
2380 .open = alc880_dig_playback_pcm_open,
2381 .close = alc880_dig_playback_pcm_close,
2382 .prepare = alc880_dig_playback_pcm_prepare
2386 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2390 /* NID is set in alc_build_pcms */
2393 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2394 static struct hda_pcm_stream alc_pcm_null_playback = {
2400 static int alc_build_pcms(struct hda_codec *codec)
2402 struct alc_spec *spec = codec->spec;
2403 struct hda_pcm *info = spec->pcm_rec;
2406 codec->num_pcms = 1;
2407 codec->pcm_info = info;
2409 info->name = spec->stream_name_analog;
2410 if (spec->stream_analog_playback) {
2411 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2412 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2413 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2415 if (spec->stream_analog_capture) {
2416 snd_assert(spec->adc_nids, return -EINVAL);
2417 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2418 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2421 if (spec->channel_mode) {
2422 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2423 for (i = 0; i < spec->num_channel_mode; i++) {
2424 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2425 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2430 /* SPDIF for stream index #1 */
2431 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2432 codec->num_pcms = 2;
2433 info = spec->pcm_rec + 1;
2434 info->name = spec->stream_name_digital;
2435 if (spec->multiout.dig_out_nid &&
2436 spec->stream_digital_playback) {
2437 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2438 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2440 if (spec->dig_in_nid &&
2441 spec->stream_digital_capture) {
2442 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2443 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2447 /* If the use of more than one ADC is requested for the current
2448 * model, configure a second analog capture-only PCM.
2450 /* Additional Analaog capture for index #2 */
2451 if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2453 codec->num_pcms = 3;
2454 info = spec->pcm_rec + 2;
2455 info->name = spec->stream_name_analog;
2456 /* No playback stream for second PCM */
2457 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2458 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2459 if (spec->stream_analog_capture) {
2460 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2461 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2468 static void alc_free(struct hda_codec *codec)
2470 struct alc_spec *spec = codec->spec;
2476 if (spec->kctl_alloc) {
2477 for (i = 0; i < spec->num_kctl_used; i++)
2478 kfree(spec->kctl_alloc[i].name);
2479 kfree(spec->kctl_alloc);
2486 static struct hda_codec_ops alc_patch_ops = {
2487 .build_controls = alc_build_controls,
2488 .build_pcms = alc_build_pcms,
2491 .unsol_event = alc_unsol_event,
2492 #ifdef CONFIG_SND_HDA_POWER_SAVE
2493 .check_power_status = alc_check_power_status,
2499 * Test configuration for debugging
2501 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2504 #ifdef CONFIG_SND_DEBUG
2505 static hda_nid_t alc880_test_dac_nids[4] = {
2506 0x02, 0x03, 0x04, 0x05
2509 static struct hda_input_mux alc880_test_capture_source = {
2518 { "Surround", 0x6 },
2522 static struct hda_channel_mode alc880_test_modes[4] = {
2529 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2530 struct snd_ctl_elem_info *uinfo)
2532 static char *texts[] = {
2533 "N/A", "Line Out", "HP Out",
2534 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2536 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2538 uinfo->value.enumerated.items = 8;
2539 if (uinfo->value.enumerated.item >= 8)
2540 uinfo->value.enumerated.item = 7;
2541 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2545 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2546 struct snd_ctl_elem_value *ucontrol)
2548 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2549 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2550 unsigned int pin_ctl, item = 0;
2552 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2553 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2554 if (pin_ctl & AC_PINCTL_OUT_EN) {
2555 if (pin_ctl & AC_PINCTL_HP_EN)
2559 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2560 switch (pin_ctl & AC_PINCTL_VREFEN) {
2561 case AC_PINCTL_VREF_HIZ: item = 3; break;
2562 case AC_PINCTL_VREF_50: item = 4; break;
2563 case AC_PINCTL_VREF_GRD: item = 5; break;
2564 case AC_PINCTL_VREF_80: item = 6; break;
2565 case AC_PINCTL_VREF_100: item = 7; break;
2568 ucontrol->value.enumerated.item[0] = item;
2572 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2573 struct snd_ctl_elem_value *ucontrol)
2575 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2576 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2577 static unsigned int ctls[] = {
2578 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2579 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2580 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2581 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2582 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2583 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2585 unsigned int old_ctl, new_ctl;
2587 old_ctl = snd_hda_codec_read(codec, nid, 0,
2588 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2589 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2590 if (old_ctl != new_ctl) {
2592 snd_hda_codec_write_cache(codec, nid, 0,
2593 AC_VERB_SET_PIN_WIDGET_CONTROL,
2595 val = ucontrol->value.enumerated.item[0] >= 3 ?
2597 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2604 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2605 struct snd_ctl_elem_info *uinfo)
2607 static char *texts[] = {
2608 "Front", "Surround", "CLFE", "Side"
2610 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2612 uinfo->value.enumerated.items = 4;
2613 if (uinfo->value.enumerated.item >= 4)
2614 uinfo->value.enumerated.item = 3;
2615 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2619 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2620 struct snd_ctl_elem_value *ucontrol)
2622 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2623 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2626 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2627 ucontrol->value.enumerated.item[0] = sel & 3;
2631 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2632 struct snd_ctl_elem_value *ucontrol)
2634 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2635 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2638 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2639 if (ucontrol->value.enumerated.item[0] != sel) {
2640 sel = ucontrol->value.enumerated.item[0] & 3;
2641 snd_hda_codec_write_cache(codec, nid, 0,
2642 AC_VERB_SET_CONNECT_SEL, sel);
2648 #define PIN_CTL_TEST(xname,nid) { \
2649 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2651 .info = alc_test_pin_ctl_info, \
2652 .get = alc_test_pin_ctl_get, \
2653 .put = alc_test_pin_ctl_put, \
2654 .private_value = nid \
2657 #define PIN_SRC_TEST(xname,nid) { \
2658 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2660 .info = alc_test_pin_src_info, \
2661 .get = alc_test_pin_src_get, \
2662 .put = alc_test_pin_src_put, \
2663 .private_value = nid \
2666 static struct snd_kcontrol_new alc880_test_mixer[] = {
2667 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2668 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2669 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2670 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2671 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2672 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2673 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2674 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2675 PIN_CTL_TEST("Front Pin Mode", 0x14),
2676 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2677 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2678 PIN_CTL_TEST("Side Pin Mode", 0x17),
2679 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2680 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2681 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2682 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2683 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2684 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2685 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2686 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2687 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2688 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2689 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2690 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2691 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2692 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2693 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2694 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2695 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2696 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2698 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2699 .name = "Channel Mode",
2700 .info = alc_ch_mode_info,
2701 .get = alc_ch_mode_get,
2702 .put = alc_ch_mode_put,
2707 static struct hda_verb alc880_test_init_verbs[] = {
2708 /* Unmute inputs of 0x0c - 0x0f */
2709 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2710 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2711 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2712 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2713 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2714 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2715 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2716 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2717 /* Vol output for 0x0c-0x0f */
2718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2719 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2720 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2721 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2722 /* Set output pins 0x14-0x17 */
2723 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2725 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2726 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2727 /* Unmute output pins 0x14-0x17 */
2728 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2729 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2730 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2731 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2732 /* Set input pins 0x18-0x1c */
2733 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2734 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2735 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2736 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2737 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2738 /* Mute input pins 0x18-0x1b */
2739 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2740 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2741 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2742 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2744 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2745 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2746 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2747 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2748 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2749 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2750 /* Analog input/passthru */
2751 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2752 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2753 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2754 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2755 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2763 static const char *alc880_models[ALC880_MODEL_LAST] = {
2764 [ALC880_3ST] = "3stack",
2765 [ALC880_TCL_S700] = "tcl",
2766 [ALC880_3ST_DIG] = "3stack-digout",
2767 [ALC880_CLEVO] = "clevo",
2768 [ALC880_5ST] = "5stack",
2769 [ALC880_5ST_DIG] = "5stack-digout",
2770 [ALC880_W810] = "w810",
2771 [ALC880_Z71V] = "z71v",
2772 [ALC880_6ST] = "6stack",
2773 [ALC880_6ST_DIG] = "6stack-digout",
2774 [ALC880_ASUS] = "asus",
2775 [ALC880_ASUS_W1V] = "asus-w1v",
2776 [ALC880_ASUS_DIG] = "asus-dig",
2777 [ALC880_ASUS_DIG2] = "asus-dig2",
2778 [ALC880_UNIWILL_DIG] = "uniwill",
2779 [ALC880_UNIWILL_P53] = "uniwill-p53",
2780 [ALC880_FUJITSU] = "fujitsu",
2781 [ALC880_F1734] = "F1734",
2783 [ALC880_LG_LW] = "lg-lw",
2784 #ifdef CONFIG_SND_DEBUG
2785 [ALC880_TEST] = "test",
2787 [ALC880_AUTO] = "auto",
2790 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2791 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2792 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2793 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2794 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2795 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2796 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2797 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2798 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2799 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2800 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2801 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2802 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2803 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2804 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2805 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2806 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2807 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2808 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2809 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2810 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2811 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2812 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2813 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2814 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2815 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2816 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
2817 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2818 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2819 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2820 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2821 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2822 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2823 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2824 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2825 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2826 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2827 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2828 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2829 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2830 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2831 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2832 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2833 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2834 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2835 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2836 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2837 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2838 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2839 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2840 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2841 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2842 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2843 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2844 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2845 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
2846 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2847 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2848 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2849 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2850 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2851 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2852 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2853 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2854 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2855 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2856 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2857 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
2858 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2859 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2864 * ALC880 codec presets
2866 static struct alc_config_preset alc880_presets[] = {
2868 .mixers = { alc880_three_stack_mixer },
2869 .init_verbs = { alc880_volume_init_verbs,
2870 alc880_pin_3stack_init_verbs },
2871 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2872 .dac_nids = alc880_dac_nids,
2873 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2874 .channel_mode = alc880_threestack_modes,
2876 .input_mux = &alc880_capture_source,
2878 [ALC880_3ST_DIG] = {
2879 .mixers = { alc880_three_stack_mixer },
2880 .init_verbs = { alc880_volume_init_verbs,
2881 alc880_pin_3stack_init_verbs },
2882 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2883 .dac_nids = alc880_dac_nids,
2884 .dig_out_nid = ALC880_DIGOUT_NID,
2885 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2886 .channel_mode = alc880_threestack_modes,
2888 .input_mux = &alc880_capture_source,
2890 [ALC880_TCL_S700] = {
2891 .mixers = { alc880_tcl_s700_mixer },
2892 .init_verbs = { alc880_volume_init_verbs,
2893 alc880_pin_tcl_S700_init_verbs,
2894 alc880_gpio2_init_verbs },
2895 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2896 .dac_nids = alc880_dac_nids,
2898 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2899 .channel_mode = alc880_2_jack_modes,
2900 .input_mux = &alc880_capture_source,
2903 .mixers = { alc880_three_stack_mixer,
2904 alc880_five_stack_mixer},
2905 .init_verbs = { alc880_volume_init_verbs,
2906 alc880_pin_5stack_init_verbs },
2907 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2908 .dac_nids = alc880_dac_nids,
2909 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2910 .channel_mode = alc880_fivestack_modes,
2911 .input_mux = &alc880_capture_source,
2913 [ALC880_5ST_DIG] = {
2914 .mixers = { alc880_three_stack_mixer,
2915 alc880_five_stack_mixer },
2916 .init_verbs = { alc880_volume_init_verbs,
2917 alc880_pin_5stack_init_verbs },
2918 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2919 .dac_nids = alc880_dac_nids,
2920 .dig_out_nid = ALC880_DIGOUT_NID,
2921 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2922 .channel_mode = alc880_fivestack_modes,
2923 .input_mux = &alc880_capture_source,
2926 .mixers = { alc880_six_stack_mixer },
2927 .init_verbs = { alc880_volume_init_verbs,
2928 alc880_pin_6stack_init_verbs },
2929 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2930 .dac_nids = alc880_6st_dac_nids,
2931 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2932 .channel_mode = alc880_sixstack_modes,
2933 .input_mux = &alc880_6stack_capture_source,
2935 [ALC880_6ST_DIG] = {
2936 .mixers = { alc880_six_stack_mixer },
2937 .init_verbs = { alc880_volume_init_verbs,
2938 alc880_pin_6stack_init_verbs },
2939 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2940 .dac_nids = alc880_6st_dac_nids,
2941 .dig_out_nid = ALC880_DIGOUT_NID,
2942 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2943 .channel_mode = alc880_sixstack_modes,
2944 .input_mux = &alc880_6stack_capture_source,
2947 .mixers = { alc880_w810_base_mixer },
2948 .init_verbs = { alc880_volume_init_verbs,
2949 alc880_pin_w810_init_verbs,
2950 alc880_gpio2_init_verbs },
2951 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2952 .dac_nids = alc880_w810_dac_nids,
2953 .dig_out_nid = ALC880_DIGOUT_NID,
2954 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2955 .channel_mode = alc880_w810_modes,
2956 .input_mux = &alc880_capture_source,
2959 .mixers = { alc880_z71v_mixer },
2960 .init_verbs = { alc880_volume_init_verbs,
2961 alc880_pin_z71v_init_verbs },
2962 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2963 .dac_nids = alc880_z71v_dac_nids,
2964 .dig_out_nid = ALC880_DIGOUT_NID,
2966 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2967 .channel_mode = alc880_2_jack_modes,
2968 .input_mux = &alc880_capture_source,
2971 .mixers = { alc880_f1734_mixer },
2972 .init_verbs = { alc880_volume_init_verbs,
2973 alc880_pin_f1734_init_verbs },
2974 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2975 .dac_nids = alc880_f1734_dac_nids,
2977 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2978 .channel_mode = alc880_2_jack_modes,
2979 .input_mux = &alc880_capture_source,
2982 .mixers = { alc880_asus_mixer },
2983 .init_verbs = { alc880_volume_init_verbs,
2984 alc880_pin_asus_init_verbs,
2985 alc880_gpio1_init_verbs },
2986 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2987 .dac_nids = alc880_asus_dac_nids,
2988 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2989 .channel_mode = alc880_asus_modes,
2991 .input_mux = &alc880_capture_source,
2993 [ALC880_ASUS_DIG] = {
2994 .mixers = { alc880_asus_mixer },
2995 .init_verbs = { alc880_volume_init_verbs,
2996 alc880_pin_asus_init_verbs,
2997 alc880_gpio1_init_verbs },
2998 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2999 .dac_nids = alc880_asus_dac_nids,
3000 .dig_out_nid = ALC880_DIGOUT_NID,
3001 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3002 .channel_mode = alc880_asus_modes,
3004 .input_mux = &alc880_capture_source,
3006 [ALC880_ASUS_DIG2] = {
3007 .mixers = { alc880_asus_mixer },
3008 .init_verbs = { alc880_volume_init_verbs,
3009 alc880_pin_asus_init_verbs,
3010 alc880_gpio2_init_verbs }, /* use GPIO2 */
3011 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3012 .dac_nids = alc880_asus_dac_nids,
3013 .dig_out_nid = ALC880_DIGOUT_NID,
3014 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3015 .channel_mode = alc880_asus_modes,
3017 .input_mux = &alc880_capture_source,
3019 [ALC880_ASUS_W1V] = {
3020 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3021 .init_verbs = { alc880_volume_init_verbs,
3022 alc880_pin_asus_init_verbs,
3023 alc880_gpio1_init_verbs },
3024 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3025 .dac_nids = alc880_asus_dac_nids,
3026 .dig_out_nid = ALC880_DIGOUT_NID,
3027 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3028 .channel_mode = alc880_asus_modes,
3030 .input_mux = &alc880_capture_source,
3032 [ALC880_UNIWILL_DIG] = {
3033 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3034 .init_verbs = { alc880_volume_init_verbs,
3035 alc880_pin_asus_init_verbs },
3036 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3037 .dac_nids = alc880_asus_dac_nids,
3038 .dig_out_nid = ALC880_DIGOUT_NID,
3039 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3040 .channel_mode = alc880_asus_modes,
3042 .input_mux = &alc880_capture_source,
3044 [ALC880_UNIWILL] = {
3045 .mixers = { alc880_uniwill_mixer },
3046 .init_verbs = { alc880_volume_init_verbs,
3047 alc880_uniwill_init_verbs },
3048 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3049 .dac_nids = alc880_asus_dac_nids,
3050 .dig_out_nid = ALC880_DIGOUT_NID,
3051 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3052 .channel_mode = alc880_threestack_modes,
3054 .input_mux = &alc880_capture_source,
3055 .unsol_event = alc880_uniwill_unsol_event,
3056 .init_hook = alc880_uniwill_automute,
3058 [ALC880_UNIWILL_P53] = {
3059 .mixers = { alc880_uniwill_p53_mixer },
3060 .init_verbs = { alc880_volume_init_verbs,
3061 alc880_uniwill_p53_init_verbs },
3062 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3063 .dac_nids = alc880_asus_dac_nids,
3064 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3065 .channel_mode = alc880_threestack_modes,
3066 .input_mux = &alc880_capture_source,
3067 .unsol_event = alc880_uniwill_p53_unsol_event,
3068 .init_hook = alc880_uniwill_p53_hp_automute,
3070 [ALC880_FUJITSU] = {
3071 .mixers = { alc880_fujitsu_mixer,
3072 alc880_pcbeep_mixer, },
3073 .init_verbs = { alc880_volume_init_verbs,
3074 alc880_uniwill_p53_init_verbs,
3075 alc880_beep_init_verbs },
3076 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3077 .dac_nids = alc880_dac_nids,
3078 .dig_out_nid = ALC880_DIGOUT_NID,
3079 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3080 .channel_mode = alc880_2_jack_modes,
3081 .input_mux = &alc880_capture_source,
3082 .unsol_event = alc880_uniwill_p53_unsol_event,
3083 .init_hook = alc880_uniwill_p53_hp_automute,
3086 .mixers = { alc880_three_stack_mixer },
3087 .init_verbs = { alc880_volume_init_verbs,
3088 alc880_pin_clevo_init_verbs },
3089 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3090 .dac_nids = alc880_dac_nids,
3092 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3093 .channel_mode = alc880_threestack_modes,
3095 .input_mux = &alc880_capture_source,
3098 .mixers = { alc880_lg_mixer },
3099 .init_verbs = { alc880_volume_init_verbs,
3100 alc880_lg_init_verbs },
3101 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3102 .dac_nids = alc880_lg_dac_nids,
3103 .dig_out_nid = ALC880_DIGOUT_NID,
3104 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3105 .channel_mode = alc880_lg_ch_modes,
3107 .input_mux = &alc880_lg_capture_source,
3108 .unsol_event = alc880_lg_unsol_event,
3109 .init_hook = alc880_lg_automute,
3110 #ifdef CONFIG_SND_HDA_POWER_SAVE
3111 .loopbacks = alc880_lg_loopbacks,
3115 .mixers = { alc880_lg_lw_mixer },
3116 .init_verbs = { alc880_volume_init_verbs,
3117 alc880_lg_lw_init_verbs },
3118 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3119 .dac_nids = alc880_dac_nids,
3120 .dig_out_nid = ALC880_DIGOUT_NID,
3121 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3122 .channel_mode = alc880_lg_lw_modes,
3123 .input_mux = &alc880_lg_lw_capture_source,
3124 .unsol_event = alc880_lg_lw_unsol_event,
3125 .init_hook = alc880_lg_lw_automute,
3127 #ifdef CONFIG_SND_DEBUG
3129 .mixers = { alc880_test_mixer },
3130 .init_verbs = { alc880_test_init_verbs },
3131 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3132 .dac_nids = alc880_test_dac_nids,
3133 .dig_out_nid = ALC880_DIGOUT_NID,
3134 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3135 .channel_mode = alc880_test_modes,
3136 .input_mux = &alc880_test_capture_source,
3142 * Automatic parse of I/O pins from the BIOS configuration
3145 #define NUM_CONTROL_ALLOC 32
3146 #define NUM_VERB_ALLOC 32
3150 ALC_CTL_WIDGET_MUTE,
3153 static struct snd_kcontrol_new alc880_control_templates[] = {
3154 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3155 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3156 HDA_BIND_MUTE(NULL, 0, 0, 0),
3159 /* add dynamic controls */
3160 static int add_control(struct alc_spec *spec, int type, const char *name,
3163 struct snd_kcontrol_new *knew;
3165 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3166 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3168 /* array + terminator */
3169 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3172 if (spec->kctl_alloc) {
3173 memcpy(knew, spec->kctl_alloc,
3174 sizeof(*knew) * spec->num_kctl_alloc);
3175 kfree(spec->kctl_alloc);
3177 spec->kctl_alloc = knew;
3178 spec->num_kctl_alloc = num;
3181 knew = &spec->kctl_alloc[spec->num_kctl_used];
3182 *knew = alc880_control_templates[type];
3183 knew->name = kstrdup(name, GFP_KERNEL);
3186 knew->private_value = val;
3187 spec->num_kctl_used++;
3191 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3192 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3193 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3194 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3195 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3196 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3197 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3198 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3199 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3200 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3201 #define ALC880_PIN_CD_NID 0x1c
3203 /* fill in the dac_nids table from the parsed pin configuration */
3204 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3205 const struct auto_pin_cfg *cfg)
3211 memset(assigned, 0, sizeof(assigned));
3212 spec->multiout.dac_nids = spec->private_dac_nids;
3214 /* check the pins hardwired to audio widget */
3215 for (i = 0; i < cfg->line_outs; i++) {
3216 nid = cfg->line_out_pins[i];
3217 if (alc880_is_fixed_pin(nid)) {
3218 int idx = alc880_fixed_pin_idx(nid);
3219 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3223 /* left pins can be connect to any audio widget */
3224 for (i = 0; i < cfg->line_outs; i++) {
3225 nid = cfg->line_out_pins[i];
3226 if (alc880_is_fixed_pin(nid))
3228 /* search for an empty channel */
3229 for (j = 0; j < cfg->line_outs; j++) {
3231 spec->multiout.dac_nids[i] =
3232 alc880_idx_to_dac(j);
3238 spec->multiout.num_dacs = cfg->line_outs;
3242 /* add playback controls from the parsed DAC table */
3243 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3244 const struct auto_pin_cfg *cfg)
3247 static const char *chname[4] = {
3248 "Front", "Surround", NULL /*CLFE*/, "Side"
3253 for (i = 0; i < cfg->line_outs; i++) {
3254 if (!spec->multiout.dac_nids[i])
3256 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3259 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3260 "Center Playback Volume",
3261 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3265 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3266 "LFE Playback Volume",
3267 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3271 err = add_control(spec, ALC_CTL_BIND_MUTE,
3272 "Center Playback Switch",
3273 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3277 err = add_control(spec, ALC_CTL_BIND_MUTE,
3278 "LFE Playback Switch",
3279 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3284 sprintf(name, "%s Playback Volume", chname[i]);
3285 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3286 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3290 sprintf(name, "%s Playback Switch", chname[i]);
3291 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3292 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3301 /* add playback controls for speaker and HP outputs */
3302 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3312 if (alc880_is_fixed_pin(pin)) {
3313 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3314 /* specify the DAC as the extra output */
3315 if (!spec->multiout.hp_nid)
3316 spec->multiout.hp_nid = nid;
3318 spec->multiout.extra_out_nid[0] = nid;
3319 /* control HP volume/switch on the output mixer amp */
3320 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3321 sprintf(name, "%s Playback Volume", pfx);
3322 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3323 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3326 sprintf(name, "%s Playback Switch", pfx);
3327 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3328 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3331 } else if (alc880_is_multi_pin(pin)) {
3332 /* set manual connection */
3333 /* we have only a switch on HP-out PIN */
3334 sprintf(name, "%s Playback Switch", pfx);
3335 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3336 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3343 /* create input playback/capture controls for the given pin */
3344 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3345 const char *ctlname,
3346 int idx, hda_nid_t mix_nid)
3351 sprintf(name, "%s Playback Volume", ctlname);
3352 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3353 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3356 sprintf(name, "%s Playback Switch", ctlname);
3357 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3358 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3364 /* create playback/capture controls for input pins */
3365 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3366 const struct auto_pin_cfg *cfg)
3368 struct hda_input_mux *imux = &spec->private_imux;
3371 for (i = 0; i < AUTO_PIN_LAST; i++) {
3372 if (alc880_is_input_pin(cfg->input_pins[i])) {
3373 idx = alc880_input_pin_idx(cfg->input_pins[i]);
3374 err = new_analog_input(spec, cfg->input_pins[i],
3375 auto_pin_cfg_labels[i],
3379 imux->items[imux->num_items].label =
3380 auto_pin_cfg_labels[i];
3381 imux->items[imux->num_items].index =
3382 alc880_input_pin_idx(cfg->input_pins[i]);
3389 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3390 hda_nid_t nid, int pin_type,
3394 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3396 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3398 /* need the manual connection? */
3399 if (alc880_is_multi_pin(nid)) {
3400 struct alc_spec *spec = codec->spec;
3401 int idx = alc880_multi_pin_idx(nid);
3402 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3403 AC_VERB_SET_CONNECT_SEL,
3404 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3408 static int get_pin_type(int line_out_type)
3410 if (line_out_type == AUTO_PIN_HP_OUT)
3416 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3418 struct alc_spec *spec = codec->spec;
3421 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3422 for (i = 0; i < spec->autocfg.line_outs; i++) {
3423 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3424 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3425 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3429 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3431 struct alc_spec *spec = codec->spec;
3434 pin = spec->autocfg.speaker_pins[0];
3435 if (pin) /* connect to front */
3436 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3437 pin = spec->autocfg.hp_pins[0];
3438 if (pin) /* connect to front */
3439 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3442 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3444 struct alc_spec *spec = codec->spec;
3447 for (i = 0; i < AUTO_PIN_LAST; i++) {
3448 hda_nid_t nid = spec->autocfg.input_pins[i];
3449 if (alc880_is_input_pin(nid)) {
3450 snd_hda_codec_write(codec, nid, 0,
3451 AC_VERB_SET_PIN_WIDGET_CONTROL,
3452 i <= AUTO_PIN_FRONT_MIC ?
3453 PIN_VREF80 : PIN_IN);
3454 if (nid != ALC880_PIN_CD_NID)
3455 snd_hda_codec_write(codec, nid, 0,
3456 AC_VERB_SET_AMP_GAIN_MUTE,
3462 /* parse the BIOS configuration and set up the alc_spec */
3463 /* return 1 if successful, 0 if the proper config is not found,
3464 * or a negative error code
3466 static int alc880_parse_auto_config(struct hda_codec *codec)
3468 struct alc_spec *spec = codec->spec;
3470 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3472 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3476 if (!spec->autocfg.line_outs)
3477 return 0; /* can't find valid BIOS pin config */
3479 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3482 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3485 err = alc880_auto_create_extra_out(spec,
3486 spec->autocfg.speaker_pins[0],
3490 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3494 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3498 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3500 if (spec->autocfg.dig_out_pin)
3501 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3502 if (spec->autocfg.dig_in_pin)
3503 spec->dig_in_nid = ALC880_DIGIN_NID;
3505 if (spec->kctl_alloc)
3506 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3508 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3510 spec->num_mux_defs = 1;
3511 spec->input_mux = &spec->private_imux;
3516 /* additional initialization for auto-configuration model */
3517 static void alc880_auto_init(struct hda_codec *codec)
3519 alc880_auto_init_multi_out(codec);
3520 alc880_auto_init_extra_out(codec);
3521 alc880_auto_init_analog_input(codec);
3525 * OK, here we have finally the patch for ALC880
3528 static int patch_alc880(struct hda_codec *codec)
3530 struct alc_spec *spec;
3534 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3540 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3543 if (board_config < 0) {
3544 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3545 "trying auto-probe from BIOS...\n");
3546 board_config = ALC880_AUTO;
3549 if (board_config == ALC880_AUTO) {
3550 /* automatic parse from the BIOS config */
3551 err = alc880_parse_auto_config(codec);
3557 "hda_codec: Cannot set up configuration "
3558 "from BIOS. Using 3-stack mode...\n");
3559 board_config = ALC880_3ST;
3563 if (board_config != ALC880_AUTO)
3564 setup_preset(spec, &alc880_presets[board_config]);
3566 spec->stream_name_analog = "ALC880 Analog";
3567 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3568 spec->stream_analog_capture = &alc880_pcm_analog_capture;
3570 spec->stream_name_digital = "ALC880 Digital";
3571 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3572 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3574 if (!spec->adc_nids && spec->input_mux) {
3575 /* check whether NID 0x07 is valid */
3576 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3578 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3579 if (wcap != AC_WID_AUD_IN) {
3580 spec->adc_nids = alc880_adc_nids_alt;
3581 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3582 spec->mixers[spec->num_mixers] =
3583 alc880_capture_alt_mixer;
3586 spec->adc_nids = alc880_adc_nids;
3587 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3588 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3593 codec->patch_ops = alc_patch_ops;
3594 if (board_config == ALC880_AUTO)
3595 spec->init_hook = alc880_auto_init;
3596 #ifdef CONFIG_SND_HDA_POWER_SAVE
3597 if (!spec->loopback.amplist)
3598 spec->loopback.amplist = alc880_loopbacks;
3609 static hda_nid_t alc260_dac_nids[1] = {
3614 static hda_nid_t alc260_adc_nids[1] = {
3619 static hda_nid_t alc260_adc_nids_alt[1] = {
3624 static hda_nid_t alc260_hp_adc_nids[2] = {
3629 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
3630 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3632 static hda_nid_t alc260_dual_adc_nids[2] = {
3637 #define ALC260_DIGOUT_NID 0x03
3638 #define ALC260_DIGIN_NID 0x06
3640 static struct hda_input_mux alc260_capture_source = {
3644 { "Front Mic", 0x1 },
3650 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3651 * headphone jack and the internal CD lines since these are the only pins at
3652 * which audio can appear. For flexibility, also allow the option of
3653 * recording the mixer output on the second ADC (ADC0 doesn't have a
3654 * connection to the mixer output).
3656 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3660 { "Mic/Line", 0x0 },
3662 { "Headphone", 0x2 },
3668 { "Mic/Line", 0x0 },
3670 { "Headphone", 0x2 },
3677 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3678 * the Fujitsu S702x, but jacks are marked differently.
3680 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3687 { "Headphone", 0x5 },
3696 { "Headphone", 0x6 },
3702 * This is just place-holder, so there's something for alc_build_pcms to look
3703 * at when it calculates the maximum number of channels. ALC260 has no mixer
3704 * element which allows changing the channel mode, so the verb list is
3707 static struct hda_channel_mode alc260_modes[1] = {
3712 /* Mixer combinations
3714 * basic: base_output + input + pc_beep + capture
3715 * HP: base_output + input + capture_alt
3716 * HP_3013: hp_3013 + input + capture
3717 * fujitsu: fujitsu + capture
3718 * acer: acer + capture
3721 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3722 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3723 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3724 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3725 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3726 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3727 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3731 static struct snd_kcontrol_new alc260_input_mixer[] = {
3732 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3733 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3734 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3735 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3736 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3737 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3738 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3739 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3743 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3744 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3745 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3749 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3750 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3751 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3752 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3753 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3754 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3755 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3756 HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3757 HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3761 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
3762 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
3764 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3765 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3766 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3767 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3768 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3769 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3770 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3771 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3772 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3773 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3774 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3775 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3776 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3780 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
3781 * versions of the ALC260 don't act on requests to enable mic bias from NID
3782 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
3783 * datasheet doesn't mention this restriction. At this stage it's not clear
3784 * whether this behaviour is intentional or is a hardware bug in chip
3785 * revisions available in early 2006. Therefore for now allow the
3786 * "Headphone Jack Mode" control to span all choices, but if it turns out
3787 * that the lack of mic bias for this NID is intentional we could change the
3788 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3790 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3791 * don't appear to make the mic bias available from the "line" jack, even
3792 * though the NID used for this jack (0x14) can supply it. The theory is
3793 * that perhaps Acer have included blocking capacitors between the ALC260
3794 * and the output jack. If this turns out to be the case for all such
3795 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3796 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3798 * The C20x Tablet series have a mono internal speaker which is controlled
3799 * via the chip's Mono sum widget and pin complex, so include the necessary
3800 * controls for such models. On models without a "mono speaker" the control
3801 * won't do anything.
3803 static struct snd_kcontrol_new alc260_acer_mixer[] = {
3804 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3805 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3806 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3807 HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3809 HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3811 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3812 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3814 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3815 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3816 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3817 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3818 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3819 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3820 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3824 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3825 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
3827 static struct snd_kcontrol_new alc260_will_mixer[] = {
3828 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3829 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3830 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3831 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3832 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3833 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3834 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3835 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3836 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3837 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3838 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3839 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3843 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3844 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3846 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3847 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3848 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3849 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3850 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3851 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3852 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3853 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3854 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3855 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3856 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3860 /* capture mixer elements */
3861 static struct snd_kcontrol_new alc260_capture_mixer[] = {
3862 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3863 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3864 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3865 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3867 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3868 /* The multiple "Capture Source" controls confuse alsamixer
3869 * So call somewhat different..
3870 * FIXME: the controls appear in the "playback" view!
3872 /* .name = "Capture Source", */
3873 .name = "Input Source",
3875 .info = alc_mux_enum_info,
3876 .get = alc_mux_enum_get,
3877 .put = alc_mux_enum_put,
3882 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3883 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3884 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3886 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3887 /* The multiple "Capture Source" controls confuse alsamixer
3888 * So call somewhat different..
3889 * FIXME: the controls appear in the "playback" view!
3891 /* .name = "Capture Source", */
3892 .name = "Input Source",
3894 .info = alc_mux_enum_info,
3895 .get = alc_mux_enum_get,
3896 .put = alc_mux_enum_put,
3902 * initialization verbs
3904 static struct hda_verb alc260_init_verbs[] = {
3905 /* Line In pin widget for input */
3906 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3907 /* CD pin widget for input */
3908 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3909 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3910 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3911 /* Mic2 (front panel) pin widget for input and vref at 80% */
3912 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3913 /* LINE-2 is used for line-out in rear */
3914 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3915 /* select line-out */
3916 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3918 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3920 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3922 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3923 /* mute capture amp left and right */
3924 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3925 /* set connection select to line in (default select for this ADC) */
3926 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3927 /* mute capture amp left and right */
3928 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3929 /* set connection select to line in (default select for this ADC) */
3930 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3931 /* set vol=0 Line-Out mixer amp left and right */
3932 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3933 /* unmute pin widget amp left and right (no gain on this amp) */
3934 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3935 /* set vol=0 HP mixer amp left and right */
3936 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3937 /* unmute pin widget amp left and right (no gain on this amp) */
3938 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3939 /* set vol=0 Mono mixer amp left and right */
3940 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3941 /* unmute pin widget amp left and right (no gain on this amp) */
3942 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3943 /* unmute LINE-2 out pin */
3944 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3945 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3948 /* mute analog inputs */
3949 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3950 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3951 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3952 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3953 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3954 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3955 /* mute Front out path */
3956 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3957 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3958 /* mute Headphone out path */
3959 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3960 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3961 /* mute Mono out path */
3962 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3963 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3967 #if 0 /* should be identical with alc260_init_verbs? */
3968 static struct hda_verb alc260_hp_init_verbs[] = {
3969 /* Headphone and output */
3970 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3972 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3973 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3974 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3975 /* Mic2 (front panel) pin widget for input and vref at 80% */
3976 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3977 /* Line In pin widget for input */
3978 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3979 /* Line-2 pin widget for output */
3980 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3981 /* CD pin widget for input */
3982 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3983 /* unmute amp left and right */
3984 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3985 /* set connection select to line in (default select for this ADC) */
3986 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3987 /* unmute Line-Out mixer amp left and right (volume = 0) */
3988 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3989 /* mute pin widget amp left and right (no gain on this amp) */
3990 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3991 /* unmute HP mixer amp left and right (volume = 0) */
3992 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3993 /* mute pin widget amp left and right (no gain on this amp) */
3994 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3995 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3998 /* mute analog inputs */
3999 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4000 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4001 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4002 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4003 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4004 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4005 /* Unmute Front out path */
4006 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4007 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4008 /* Unmute Headphone out path */
4009 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4010 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4011 /* Unmute Mono out path */
4012 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4013 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4018 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4019 /* Line out and output */
4020 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4022 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4023 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4024 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4025 /* Mic2 (front panel) pin widget for input and vref at 80% */
4026 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4027 /* Line In pin widget for input */
4028 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4029 /* Headphone pin widget for output */
4030 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4031 /* CD pin widget for input */
4032 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4033 /* unmute amp left and right */
4034 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4035 /* set connection select to line in (default select for this ADC) */
4036 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4037 /* unmute Line-Out mixer amp left and right (volume = 0) */
4038 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4039 /* mute pin widget amp left and right (no gain on this amp) */
4040 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4041 /* unmute HP mixer amp left and right (volume = 0) */
4042 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4043 /* mute pin widget amp left and right (no gain on this amp) */
4044 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4045 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4048 /* mute analog inputs */
4049 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4050 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4051 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4052 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4053 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4054 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4055 /* Unmute Front out path */
4056 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4057 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4058 /* Unmute Headphone out path */
4059 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4060 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4061 /* Unmute Mono out path */
4062 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4063 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4067 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4068 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4069 * audio = 0x16, internal speaker = 0x10.
4071 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4072 /* Disable all GPIOs */
4073 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4074 /* Internal speaker is connected to headphone pin */
4075 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4076 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4077 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4078 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4079 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4080 /* Ensure all other unused pins are disabled and muted. */
4081 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4082 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4083 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4084 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4085 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4086 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4087 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4088 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4090 /* Disable digital (SPDIF) pins */
4091 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4092 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4094 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4095 * when acting as an output.
4097 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4099 /* Start with output sum widgets muted and their output gains at min */
4100 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4101 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4102 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4103 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4104 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4105 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4106 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4107 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4108 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4110 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4111 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4112 /* Unmute Line1 pin widget output buffer since it starts as an output.
4113 * If the pin mode is changed by the user the pin mode control will
4114 * take care of enabling the pin's input/output buffers as needed.
4115 * Therefore there's no need to enable the input buffer at this
4118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4119 /* Unmute input buffer of pin widget used for Line-in (no equiv
4122 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4124 /* Mute capture amp left and right */
4125 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4126 /* Set ADC connection select to match default mixer setting - line
4129 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4131 /* Do the same for the second ADC: mute capture input amp and
4132 * set ADC connection to line in (on mic1 pin)
4134 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4135 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4137 /* Mute all inputs to mixer widget (even unconnected ones) */
4138 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4139 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4140 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4141 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4142 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4143 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4144 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4145 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4150 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4151 * similar laptops (adapted from Fujitsu init verbs).
4153 static struct hda_verb alc260_acer_init_verbs[] = {
4154 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4155 * the headphone jack. Turn this on and rely on the standard mute
4156 * methods whenever the user wants to turn these outputs off.
4158 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4159 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4160 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4161 /* Internal speaker/Headphone jack is connected to Line-out pin */
4162 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4163 /* Internal microphone/Mic jack is connected to Mic1 pin */
4164 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4165 /* Line In jack is connected to Line1 pin */
4166 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4167 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4168 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4169 /* Ensure all other unused pins are disabled and muted. */
4170 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4171 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4172 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4173 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4174 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4175 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4176 /* Disable digital (SPDIF) pins */
4177 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4178 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4180 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4181 * bus when acting as outputs.
4183 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4184 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4186 /* Start with output sum widgets muted and their output gains at min */
4187 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4188 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4189 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4190 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4191 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4192 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4193 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4194 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4195 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4197 /* Unmute Line-out pin widget amp left and right
4198 * (no equiv mixer ctrl)
4200 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4201 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4202 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4203 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4204 * inputs. If the pin mode is changed by the user the pin mode control
4205 * will take care of enabling the pin's input/output buffers as needed.
4206 * Therefore there's no need to enable the input buffer at this
4209 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4210 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4212 /* Mute capture amp left and right */
4213 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4214 /* Set ADC connection select to match default mixer setting - mic
4217 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4219 /* Do similar with the second ADC: mute capture input amp and
4220 * set ADC connection to mic to match ALSA's default state.
4222 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4223 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4225 /* Mute all inputs to mixer widget (even unconnected ones) */
4226 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4229 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4230 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4231 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4232 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4233 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4238 static struct hda_verb alc260_will_verbs[] = {
4239 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4240 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4241 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4242 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4243 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4244 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4248 static struct hda_verb alc260_replacer_672v_verbs[] = {
4249 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4250 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4251 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4253 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4254 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4255 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4257 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4261 /* toggle speaker-output according to the hp-jack state */
4262 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4264 unsigned int present;
4266 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4267 present = snd_hda_codec_read(codec, 0x0f, 0,
4268 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4270 snd_hda_codec_write_cache(codec, 0x01, 0,
4271 AC_VERB_SET_GPIO_DATA, 1);
4272 snd_hda_codec_write_cache(codec, 0x0f, 0,
4273 AC_VERB_SET_PIN_WIDGET_CONTROL,
4276 snd_hda_codec_write_cache(codec, 0x01, 0,
4277 AC_VERB_SET_GPIO_DATA, 0);
4278 snd_hda_codec_write_cache(codec, 0x0f, 0,
4279 AC_VERB_SET_PIN_WIDGET_CONTROL,
4284 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4287 if ((res >> 26) == ALC880_HP_EVENT)
4288 alc260_replacer_672v_automute(codec);
4291 /* Test configuration for debugging, modelled after the ALC880 test
4294 #ifdef CONFIG_SND_DEBUG
4295 static hda_nid_t alc260_test_dac_nids[1] = {
4298 static hda_nid_t alc260_test_adc_nids[2] = {
4301 /* For testing the ALC260, each input MUX needs its own definition since
4302 * the signal assignments are different. This assumes that the first ADC
4305 static struct hda_input_mux alc260_test_capture_sources[2] = {
4309 { "MIC1 pin", 0x0 },
4310 { "MIC2 pin", 0x1 },
4311 { "LINE1 pin", 0x2 },
4312 { "LINE2 pin", 0x3 },
4314 { "LINE-OUT pin", 0x5 },
4315 { "HP-OUT pin", 0x6 },
4321 { "MIC1 pin", 0x0 },
4322 { "MIC2 pin", 0x1 },
4323 { "LINE1 pin", 0x2 },
4324 { "LINE2 pin", 0x3 },
4327 { "LINE-OUT pin", 0x6 },
4328 { "HP-OUT pin", 0x7 },
4332 static struct snd_kcontrol_new alc260_test_mixer[] = {
4333 /* Output driver widgets */
4334 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4335 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4336 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4337 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4338 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4339 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4341 /* Modes for retasking pin widgets
4342 * Note: the ALC260 doesn't seem to act on requests to enable mic
4343 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4344 * mention this restriction. At this stage it's not clear whether
4345 * this behaviour is intentional or is a hardware bug in chip
4346 * revisions available at least up until early 2006. Therefore for
4347 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4348 * choices, but if it turns out that the lack of mic bias for these
4349 * NIDs is intentional we could change their modes from
4350 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4352 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4353 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4354 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4355 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4356 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4357 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4359 /* Loopback mixer controls */
4360 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4361 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4362 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4363 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4364 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4365 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4366 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4367 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4368 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4369 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4370 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4371 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4372 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4373 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4374 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4375 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4377 /* Controls for GPIO pins, assuming they are configured as outputs */
4378 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4379 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4380 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4381 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4383 /* Switches to allow the digital IO pins to be enabled. The datasheet
4384 * is ambigious as to which NID is which; testing on laptops which
4385 * make this output available should provide clarification.
4387 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4388 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4390 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4391 * this output to turn on an external amplifier.
4393 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4394 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4398 static struct hda_verb alc260_test_init_verbs[] = {
4399 /* Enable all GPIOs as outputs with an initial value of 0 */
4400 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4401 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4402 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4404 /* Enable retasking pins as output, initially without power amp */
4405 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4406 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4407 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4408 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4409 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4410 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4412 /* Disable digital (SPDIF) pins initially, but users can enable
4413 * them via a mixer switch. In the case of SPDIF-out, this initverb
4414 * payload also sets the generation to 0, output to be in "consumer"
4415 * PCM format, copyright asserted, no pre-emphasis and no validity
4418 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4419 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4421 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4422 * OUT1 sum bus when acting as an output.
4424 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4425 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4426 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4427 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4429 /* Start with output sum widgets muted and their output gains at min */
4430 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4431 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4432 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4433 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4434 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4435 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4436 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4437 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4438 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4440 /* Unmute retasking pin widget output buffers since the default
4441 * state appears to be output. As the pin mode is changed by the
4442 * user the pin mode control will take care of enabling the pin's
4443 * input/output buffers as needed.
4445 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4446 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4448 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4449 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4450 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4451 /* Also unmute the mono-out pin widget */
4452 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4454 /* Mute capture amp left and right */
4455 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4456 /* Set ADC connection select to match default mixer setting (mic1
4459 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4461 /* Do the same for the second ADC: mute capture input amp and
4462 * set ADC connection to mic1 pin
4464 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4465 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4467 /* Mute all inputs to mixer widget (even unconnected ones) */
4468 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4469 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4470 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4471 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4472 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4473 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4474 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4475 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4481 static struct hda_pcm_stream alc260_pcm_analog_playback = {
4487 static struct hda_pcm_stream alc260_pcm_analog_capture = {
4493 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
4494 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
4497 * for BIOS auto-configuration
4500 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4504 unsigned long vol_val, sw_val;
4508 if (nid >= 0x0f && nid < 0x11) {
4509 nid_vol = nid - 0x7;
4510 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4511 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4512 } else if (nid == 0x11) {
4513 nid_vol = nid - 0x7;
4514 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4515 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4516 } else if (nid >= 0x12 && nid <= 0x15) {
4518 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4519 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4523 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4524 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4527 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4528 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4534 /* add playback controls from the parsed DAC table */
4535 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4536 const struct auto_pin_cfg *cfg)
4541 spec->multiout.num_dacs = 1;
4542 spec->multiout.dac_nids = spec->private_dac_nids;
4543 spec->multiout.dac_nids[0] = 0x02;
4545 nid = cfg->line_out_pins[0];
4547 err = alc260_add_playback_controls(spec, nid, "Front");
4552 nid = cfg->speaker_pins[0];
4554 err = alc260_add_playback_controls(spec, nid, "Speaker");
4559 nid = cfg->hp_pins[0];
4561 err = alc260_add_playback_controls(spec, nid, "Headphone");
4568 /* create playback/capture controls for input pins */
4569 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4570 const struct auto_pin_cfg *cfg)
4572 struct hda_input_mux *imux = &spec->private_imux;
4575 for (i = 0; i < AUTO_PIN_LAST; i++) {
4576 if (cfg->input_pins[i] >= 0x12) {
4577 idx = cfg->input_pins[i] - 0x12;
4578 err = new_analog_input(spec, cfg->input_pins[i],
4579 auto_pin_cfg_labels[i], idx,
4583 imux->items[imux->num_items].label =
4584 auto_pin_cfg_labels[i];
4585 imux->items[imux->num_items].index = idx;
4588 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4589 idx = cfg->input_pins[i] - 0x09;
4590 err = new_analog_input(spec, cfg->input_pins[i],
4591 auto_pin_cfg_labels[i], idx,
4595 imux->items[imux->num_items].label =
4596 auto_pin_cfg_labels[i];
4597 imux->items[imux->num_items].index = idx;
4604 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4605 hda_nid_t nid, int pin_type,
4609 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4611 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4613 /* need the manual connection? */
4615 int idx = nid - 0x12;
4616 snd_hda_codec_write(codec, idx + 0x0b, 0,
4617 AC_VERB_SET_CONNECT_SEL, sel_idx);
4621 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4623 struct alc_spec *spec = codec->spec;
4626 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4627 nid = spec->autocfg.line_out_pins[0];
4629 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4630 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4633 nid = spec->autocfg.speaker_pins[0];
4635 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4637 nid = spec->autocfg.hp_pins[0];
4639 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4642 #define ALC260_PIN_CD_NID 0x16
4643 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4645 struct alc_spec *spec = codec->spec;
4648 for (i = 0; i < AUTO_PIN_LAST; i++) {
4649 hda_nid_t nid = spec->autocfg.input_pins[i];
4651 snd_hda_codec_write(codec, nid, 0,
4652 AC_VERB_SET_PIN_WIDGET_CONTROL,
4653 i <= AUTO_PIN_FRONT_MIC ?
4654 PIN_VREF80 : PIN_IN);
4655 if (nid != ALC260_PIN_CD_NID)
4656 snd_hda_codec_write(codec, nid, 0,
4657 AC_VERB_SET_AMP_GAIN_MUTE,
4664 * generic initialization of ADC, input mixers and output mixers
4666 static struct hda_verb alc260_volume_init_verbs[] = {
4668 * Unmute ADC0-1 and set the default input to mic-in
4670 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4671 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4672 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4673 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4675 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4677 * Note: PASD motherboards uses the Line In 2 as the input for
4678 * front panel mic (mic 2)
4680 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4681 /* mute analog inputs */
4682 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4685 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4686 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4689 * Set up output mixers (0x08 - 0x0a)
4691 /* set vol=0 to output mixers */
4692 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4693 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4694 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4695 /* set up input amps for analog loopback */
4696 /* Amp Indices: DAC = 0, mixer = 1 */
4697 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4698 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4699 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4700 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4701 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4702 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4707 static int alc260_parse_auto_config(struct hda_codec *codec)
4709 struct alc_spec *spec = codec->spec;
4712 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4714 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4718 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4721 if (!spec->kctl_alloc)
4722 return 0; /* can't find valid BIOS pin config */
4723 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4727 spec->multiout.max_channels = 2;
4729 if (spec->autocfg.dig_out_pin)
4730 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4731 if (spec->kctl_alloc)
4732 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4734 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4736 spec->num_mux_defs = 1;
4737 spec->input_mux = &spec->private_imux;
4739 /* check whether NID 0x04 is valid */
4740 wcap = get_wcaps(codec, 0x04);
4741 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4742 if (wcap != AC_WID_AUD_IN) {
4743 spec->adc_nids = alc260_adc_nids_alt;
4744 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4745 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4747 spec->adc_nids = alc260_adc_nids;
4748 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4749 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4756 /* additional initialization for auto-configuration model */
4757 static void alc260_auto_init(struct hda_codec *codec)
4759 alc260_auto_init_multi_out(codec);
4760 alc260_auto_init_analog_input(codec);
4763 #ifdef CONFIG_SND_HDA_POWER_SAVE
4764 static struct hda_amp_list alc260_loopbacks[] = {
4765 { 0x07, HDA_INPUT, 0 },
4766 { 0x07, HDA_INPUT, 1 },
4767 { 0x07, HDA_INPUT, 2 },
4768 { 0x07, HDA_INPUT, 3 },
4769 { 0x07, HDA_INPUT, 4 },
4775 * ALC260 configurations
4777 static const char *alc260_models[ALC260_MODEL_LAST] = {
4778 [ALC260_BASIC] = "basic",
4780 [ALC260_HP_3013] = "hp-3013",
4781 [ALC260_FUJITSU_S702X] = "fujitsu",
4782 [ALC260_ACER] = "acer",
4783 [ALC260_WILL] = "will",
4784 [ALC260_REPLACER_672V] = "replacer",
4785 #ifdef CONFIG_SND_DEBUG
4786 [ALC260_TEST] = "test",
4788 [ALC260_AUTO] = "auto",
4791 static struct snd_pci_quirk alc260_cfg_tbl[] = {
4792 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4793 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4794 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4795 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4796 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4797 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4798 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4799 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4800 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4801 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4802 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4803 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4804 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4805 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4806 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4807 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4808 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4809 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4813 static struct alc_config_preset alc260_presets[] = {
4815 .mixers = { alc260_base_output_mixer,
4817 alc260_pc_beep_mixer,
4818 alc260_capture_mixer },
4819 .init_verbs = { alc260_init_verbs },
4820 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4821 .dac_nids = alc260_dac_nids,
4822 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4823 .adc_nids = alc260_adc_nids,
4824 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4825 .channel_mode = alc260_modes,
4826 .input_mux = &alc260_capture_source,
4829 .mixers = { alc260_base_output_mixer,
4831 alc260_capture_alt_mixer },
4832 .init_verbs = { alc260_init_verbs },
4833 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4834 .dac_nids = alc260_dac_nids,
4835 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4836 .adc_nids = alc260_hp_adc_nids,
4837 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4838 .channel_mode = alc260_modes,
4839 .input_mux = &alc260_capture_source,
4841 [ALC260_HP_3013] = {
4842 .mixers = { alc260_hp_3013_mixer,
4844 alc260_capture_alt_mixer },
4845 .init_verbs = { alc260_hp_3013_init_verbs },
4846 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4847 .dac_nids = alc260_dac_nids,
4848 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4849 .adc_nids = alc260_hp_adc_nids,
4850 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4851 .channel_mode = alc260_modes,
4852 .input_mux = &alc260_capture_source,
4854 [ALC260_FUJITSU_S702X] = {
4855 .mixers = { alc260_fujitsu_mixer,
4856 alc260_capture_mixer },
4857 .init_verbs = { alc260_fujitsu_init_verbs },
4858 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4859 .dac_nids = alc260_dac_nids,
4860 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4861 .adc_nids = alc260_dual_adc_nids,
4862 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4863 .channel_mode = alc260_modes,
4864 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4865 .input_mux = alc260_fujitsu_capture_sources,
4868 .mixers = { alc260_acer_mixer,
4869 alc260_capture_mixer },
4870 .init_verbs = { alc260_acer_init_verbs },
4871 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4872 .dac_nids = alc260_dac_nids,
4873 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4874 .adc_nids = alc260_dual_adc_nids,
4875 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4876 .channel_mode = alc260_modes,
4877 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4878 .input_mux = alc260_acer_capture_sources,
4881 .mixers = { alc260_will_mixer,
4882 alc260_capture_mixer },
4883 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
4884 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4885 .dac_nids = alc260_dac_nids,
4886 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4887 .adc_nids = alc260_adc_nids,
4888 .dig_out_nid = ALC260_DIGOUT_NID,
4889 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4890 .channel_mode = alc260_modes,
4891 .input_mux = &alc260_capture_source,
4893 [ALC260_REPLACER_672V] = {
4894 .mixers = { alc260_replacer_672v_mixer,
4895 alc260_capture_mixer },
4896 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4897 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4898 .dac_nids = alc260_dac_nids,
4899 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4900 .adc_nids = alc260_adc_nids,
4901 .dig_out_nid = ALC260_DIGOUT_NID,
4902 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4903 .channel_mode = alc260_modes,
4904 .input_mux = &alc260_capture_source,
4905 .unsol_event = alc260_replacer_672v_unsol_event,
4906 .init_hook = alc260_replacer_672v_automute,
4908 #ifdef CONFIG_SND_DEBUG
4910 .mixers = { alc260_test_mixer,
4911 alc260_capture_mixer },
4912 .init_verbs = { alc260_test_init_verbs },
4913 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4914 .dac_nids = alc260_test_dac_nids,
4915 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4916 .adc_nids = alc260_test_adc_nids,
4917 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4918 .channel_mode = alc260_modes,
4919 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4920 .input_mux = alc260_test_capture_sources,
4925 static int patch_alc260(struct hda_codec *codec)
4927 struct alc_spec *spec;
4928 int err, board_config;
4930 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4936 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4939 if (board_config < 0) {
4940 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4941 "trying auto-probe from BIOS...\n");
4942 board_config = ALC260_AUTO;
4945 if (board_config == ALC260_AUTO) {
4946 /* automatic parse from the BIOS config */
4947 err = alc260_parse_auto_config(codec);
4953 "hda_codec: Cannot set up configuration "
4954 "from BIOS. Using base mode...\n");
4955 board_config = ALC260_BASIC;
4959 if (board_config != ALC260_AUTO)
4960 setup_preset(spec, &alc260_presets[board_config]);
4962 spec->stream_name_analog = "ALC260 Analog";
4963 spec->stream_analog_playback = &alc260_pcm_analog_playback;
4964 spec->stream_analog_capture = &alc260_pcm_analog_capture;
4966 spec->stream_name_digital = "ALC260 Digital";
4967 spec->stream_digital_playback = &alc260_pcm_digital_playback;
4968 spec->stream_digital_capture = &alc260_pcm_digital_capture;
4970 codec->patch_ops = alc_patch_ops;
4971 if (board_config == ALC260_AUTO)
4972 spec->init_hook = alc260_auto_init;
4973 #ifdef CONFIG_SND_HDA_POWER_SAVE
4974 if (!spec->loopback.amplist)
4975 spec->loopback.amplist = alc260_loopbacks;
4985 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4986 * configuration. Each pin widget can choose any input DACs and a mixer.
4987 * Each ADC is connected from a mixer of all inputs. This makes possible
4988 * 6-channel independent captures.
4990 * In addition, an independent DAC for the multi-playback (not used in this
4993 #define ALC882_DIGOUT_NID 0x06
4994 #define ALC882_DIGIN_NID 0x0a
4996 static struct hda_channel_mode alc882_ch_modes[1] = {
5000 static hda_nid_t alc882_dac_nids[4] = {
5001 /* front, rear, clfe, rear_surr */
5002 0x02, 0x03, 0x04, 0x05
5005 /* identical with ALC880 */
5006 #define alc882_adc_nids alc880_adc_nids
5007 #define alc882_adc_nids_alt alc880_adc_nids_alt
5010 /* FIXME: should be a matrix-type input source selection */
5012 static struct hda_input_mux alc882_capture_source = {
5016 { "Front Mic", 0x1 },
5021 #define alc882_mux_enum_info alc_mux_enum_info
5022 #define alc882_mux_enum_get alc_mux_enum_get
5024 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5025 struct snd_ctl_elem_value *ucontrol)
5027 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5028 struct alc_spec *spec = codec->spec;
5029 const struct hda_input_mux *imux = spec->input_mux;
5030 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5031 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5032 hda_nid_t nid = capture_mixers[adc_idx];
5033 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5034 unsigned int i, idx;
5036 idx = ucontrol->value.enumerated.item[0];
5037 if (idx >= imux->num_items)
5038 idx = imux->num_items - 1;
5039 if (*cur_val == idx)
5041 for (i = 0; i < imux->num_items; i++) {
5042 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5043 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5044 imux->items[i].index,
5054 static struct hda_verb alc882_3ST_ch2_init[] = {
5055 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5056 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5057 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5058 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5065 static struct hda_verb alc882_3ST_ch6_init[] = {
5066 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5067 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5068 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5069 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5070 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5071 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5075 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5076 { 2, alc882_3ST_ch2_init },
5077 { 6, alc882_3ST_ch6_init },
5083 static struct hda_verb alc882_sixstack_ch6_init[] = {
5084 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5085 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5086 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5087 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5094 static struct hda_verb alc882_sixstack_ch8_init[] = {
5095 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5096 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5097 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5098 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5102 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5103 { 6, alc882_sixstack_ch6_init },
5104 { 8, alc882_sixstack_ch8_init },
5108 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5114 static struct hda_verb alc885_mbp_ch2_init[] = {
5115 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5116 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5117 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5124 static struct hda_verb alc885_mbp_ch6_init[] = {
5125 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5126 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5127 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5128 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5129 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5133 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5134 { 2, alc885_mbp_ch2_init },
5135 { 6, alc885_mbp_ch6_init },
5139 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5140 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5142 static struct snd_kcontrol_new alc882_base_mixer[] = {
5143 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5144 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5145 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5146 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5147 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5148 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5149 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5150 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5151 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5152 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5153 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5154 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5155 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5156 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5157 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5158 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5159 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5160 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5161 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5162 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5163 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5164 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5165 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5169 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5170 HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT),
5171 HDA_BIND_MUTE ("Master Switch", 0x0c, 0x02, HDA_INPUT),
5172 HDA_CODEC_MUTE ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT),
5173 HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT),
5174 HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT),
5175 HDA_CODEC_MUTE ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT),
5176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5177 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5178 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT),
5179 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5182 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5183 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5184 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5185 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5186 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5187 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5188 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5189 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5190 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5192 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5193 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5197 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5198 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5199 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5200 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5201 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5202 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5203 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5204 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5205 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5206 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5207 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5208 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5209 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5210 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5214 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5215 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5217 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5218 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5219 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5220 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5221 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5222 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5223 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5224 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5225 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5226 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5227 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5228 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5229 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5230 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5234 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5235 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5236 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5237 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5238 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5239 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5240 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5241 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5242 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5243 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5244 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5245 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5246 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5250 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5252 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5253 .name = "Channel Mode",
5254 .info = alc_ch_mode_info,
5255 .get = alc_ch_mode_get,
5256 .put = alc_ch_mode_put,
5261 static struct hda_verb alc882_init_verbs[] = {
5262 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5264 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5265 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5267 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5268 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5269 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5271 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5272 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5273 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5275 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5276 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5277 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5279 /* Front Pin: output 0 (0x0c) */
5280 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5281 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5282 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5283 /* Rear Pin: output 1 (0x0d) */
5284 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5285 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5286 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5287 /* CLFE Pin: output 2 (0x0e) */
5288 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5289 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5290 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5291 /* Side Pin: output 3 (0x0f) */
5292 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5293 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5294 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5295 /* Mic (rear) pin: input vref at 80% */
5296 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5297 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5298 /* Front Mic pin: input vref at 80% */
5299 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5300 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5301 /* Line In pin: input */
5302 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5303 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5304 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5305 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5306 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5307 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5308 /* CD pin widget for input */
5309 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5311 /* FIXME: use matrix-type input source selection */
5312 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5313 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5314 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5315 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5316 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5317 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5319 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5320 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5321 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5322 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5325 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5327 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5328 /* ADC1: mute amp left and right */
5329 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5330 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5331 /* ADC2: mute amp left and right */
5332 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5333 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5334 /* ADC3: mute amp left and right */
5335 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5336 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5341 static struct hda_verb alc882_eapd_verbs[] = {
5342 /* change to EAPD mode */
5343 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5344 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5349 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5350 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5351 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5352 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5353 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5354 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5355 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5356 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5360 static struct hda_verb alc882_macpro_init_verbs[] = {
5361 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5362 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5363 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5364 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5365 /* Front Pin: output 0 (0x0c) */
5366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5367 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5368 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5369 /* Front Mic pin: input vref at 80% */
5370 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5371 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5372 /* Speaker: output */
5373 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5374 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5375 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5376 /* Headphone output (output 0 - 0x0c) */
5377 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5378 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5379 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5381 /* FIXME: use matrix-type input source selection */
5382 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5383 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5384 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5385 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5386 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5387 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5389 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5390 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5391 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5392 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5394 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5395 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5396 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5397 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5398 /* ADC1: mute amp left and right */
5399 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5400 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5401 /* ADC2: mute amp left and right */
5402 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5403 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5404 /* ADC3: mute amp left and right */
5405 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5406 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5411 /* Macbook Pro rev3 */
5412 static struct hda_verb alc885_mbp3_init_verbs[] = {
5413 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5418 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5419 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5420 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5421 /* Front Pin: output 0 (0x0c) */
5422 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5423 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5424 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5425 /* HP Pin: output 0 (0x0d) */
5426 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5427 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5428 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5429 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5430 /* Mic (rear) pin: input vref at 80% */
5431 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5432 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5433 /* Front Mic pin: input vref at 80% */
5434 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5435 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5436 /* Line In pin: use output 1 when in LineOut mode */
5437 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5438 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5439 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5441 /* FIXME: use matrix-type input source selection */
5442 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5443 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5444 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5449 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5450 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5451 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5452 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5454 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5455 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5456 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5457 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5458 /* ADC1: mute amp left and right */
5459 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5460 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5461 /* ADC2: mute amp left and right */
5462 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5463 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5464 /* ADC3: mute amp left and right */
5465 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5466 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5471 /* iMac 24 mixer. */
5472 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5473 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5474 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5478 /* iMac 24 init verbs. */
5479 static struct hda_verb alc885_imac24_init_verbs[] = {
5480 /* Internal speakers: output 0 (0x0c) */
5481 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5482 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5483 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5484 /* Internal speakers: output 0 (0x0c) */
5485 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5486 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5487 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5488 /* Headphone: output 0 (0x0c) */
5489 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5490 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5491 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5492 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5493 /* Front Mic: input vref at 80% */
5494 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5495 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5499 /* Toggle speaker-output according to the hp-jack state */
5500 static void alc885_imac24_automute(struct hda_codec *codec)
5502 unsigned int present;
5504 present = snd_hda_codec_read(codec, 0x14, 0,
5505 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5506 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5507 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5508 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5509 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5512 /* Processes unsolicited events. */
5513 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5516 /* Headphone insertion or removal. */
5517 if ((res >> 26) == ALC880_HP_EVENT)
5518 alc885_imac24_automute(codec);
5521 static void alc885_mbp3_automute(struct hda_codec *codec)
5523 unsigned int present;
5525 present = snd_hda_codec_read(codec, 0x15, 0,
5526 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5527 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
5528 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5529 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5530 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5533 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5536 /* Headphone insertion or removal. */
5537 if ((res >> 26) == ALC880_HP_EVENT)
5538 alc885_mbp3_automute(codec);
5542 static struct hda_verb alc882_targa_verbs[] = {
5543 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5544 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5546 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5547 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5549 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5550 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5551 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5553 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5554 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5555 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5556 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5560 /* toggle speaker-output according to the hp-jack state */
5561 static void alc882_targa_automute(struct hda_codec *codec)
5563 unsigned int present;
5565 present = snd_hda_codec_read(codec, 0x14, 0,
5566 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5567 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5568 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5569 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5573 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5575 /* Looks like the unsol event is incompatible with the standard
5576 * definition. 4bit tag is placed at 26 bit!
5578 if (((res >> 26) == ALC880_HP_EVENT)) {
5579 alc882_targa_automute(codec);
5583 static struct hda_verb alc882_asus_a7j_verbs[] = {
5584 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5585 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5587 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5588 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5589 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5591 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5592 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5593 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5595 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5596 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5597 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5601 static struct hda_verb alc882_asus_a7m_verbs[] = {
5602 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5603 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5605 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5606 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5607 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5609 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5610 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5611 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5613 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5614 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5615 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5619 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5621 unsigned int gpiostate, gpiomask, gpiodir;
5623 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5624 AC_VERB_GET_GPIO_DATA, 0);
5627 gpiostate |= (1 << pin);
5629 gpiostate &= ~(1 << pin);
5631 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5632 AC_VERB_GET_GPIO_MASK, 0);
5633 gpiomask |= (1 << pin);
5635 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5636 AC_VERB_GET_GPIO_DIRECTION, 0);
5637 gpiodir |= (1 << pin);
5640 snd_hda_codec_write(codec, codec->afg, 0,
5641 AC_VERB_SET_GPIO_MASK, gpiomask);
5642 snd_hda_codec_write(codec, codec->afg, 0,
5643 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5647 snd_hda_codec_write(codec, codec->afg, 0,
5648 AC_VERB_SET_GPIO_DATA, gpiostate);
5651 /* set up GPIO at initialization */
5652 static void alc885_macpro_init_hook(struct hda_codec *codec)
5654 alc882_gpio_mute(codec, 0, 0);
5655 alc882_gpio_mute(codec, 1, 0);
5658 /* set up GPIO and update auto-muting at initialization */
5659 static void alc885_imac24_init_hook(struct hda_codec *codec)
5661 alc885_macpro_init_hook(codec);
5662 alc885_imac24_automute(codec);
5666 * generic initialization of ADC, input mixers and output mixers
5668 static struct hda_verb alc882_auto_init_verbs[] = {
5670 * Unmute ADC0-2 and set the default input to mic-in
5672 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5673 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5674 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5675 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5676 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5677 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5679 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5681 * Note: PASD motherboards uses the Line In 2 as the input for
5682 * front panel mic (mic 2)
5684 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5685 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5688 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5692 * Set up output mixers (0x0c - 0x0f)
5694 /* set vol=0 to output mixers */
5695 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5696 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5697 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5698 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5699 /* set up input amps for analog loopback */
5700 /* Amp Indices: DAC = 0, mixer = 1 */
5701 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5703 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5704 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5705 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5706 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5707 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5708 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5709 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5710 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5712 /* FIXME: use matrix-type input source selection */
5713 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5714 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5715 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5716 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5717 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5718 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5720 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5721 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5722 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5723 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5725 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5726 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5727 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5728 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5733 /* capture mixer elements */
5734 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5735 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5736 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5737 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5738 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5741 /* The multiple "Capture Source" controls confuse alsamixer
5742 * So call somewhat different..
5743 * FIXME: the controls appear in the "playback" view!
5745 /* .name = "Capture Source", */
5746 .name = "Input Source",
5748 .info = alc882_mux_enum_info,
5749 .get = alc882_mux_enum_get,
5750 .put = alc882_mux_enum_put,
5755 static struct snd_kcontrol_new alc882_capture_mixer[] = {
5756 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5757 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5758 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5759 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5760 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5761 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5763 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5764 /* The multiple "Capture Source" controls confuse alsamixer
5765 * So call somewhat different..
5766 * FIXME: the controls appear in the "playback" view!
5768 /* .name = "Capture Source", */
5769 .name = "Input Source",
5771 .info = alc882_mux_enum_info,
5772 .get = alc882_mux_enum_get,
5773 .put = alc882_mux_enum_put,
5778 #ifdef CONFIG_SND_HDA_POWER_SAVE
5779 #define alc882_loopbacks alc880_loopbacks
5782 /* pcm configuration: identiacal with ALC880 */
5783 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
5784 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
5785 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
5786 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
5789 * configuration and preset
5791 static const char *alc882_models[ALC882_MODEL_LAST] = {
5792 [ALC882_3ST_DIG] = "3stack-dig",
5793 [ALC882_6ST_DIG] = "6stack-dig",
5794 [ALC882_ARIMA] = "arima",
5795 [ALC882_W2JC] = "w2jc",
5796 [ALC882_TARGA] = "targa",
5797 [ALC882_ASUS_A7J] = "asus-a7j",
5798 [ALC882_ASUS_A7M] = "asus-a7m",
5799 [ALC885_MACPRO] = "macpro",
5800 [ALC885_MBP3] = "mbp3",
5801 [ALC885_IMAC24] = "imac24",
5802 [ALC882_AUTO] = "auto",
5805 static struct snd_pci_quirk alc882_cfg_tbl[] = {
5806 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5807 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5808 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
5809 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
5810 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5811 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5812 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5813 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5814 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
5815 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5816 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5820 static struct alc_config_preset alc882_presets[] = {
5821 [ALC882_3ST_DIG] = {
5822 .mixers = { alc882_base_mixer },
5823 .init_verbs = { alc882_init_verbs },
5824 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5825 .dac_nids = alc882_dac_nids,
5826 .dig_out_nid = ALC882_DIGOUT_NID,
5827 .dig_in_nid = ALC882_DIGIN_NID,
5828 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5829 .channel_mode = alc882_ch_modes,
5831 .input_mux = &alc882_capture_source,
5833 [ALC882_6ST_DIG] = {
5834 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5835 .init_verbs = { alc882_init_verbs },
5836 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5837 .dac_nids = alc882_dac_nids,
5838 .dig_out_nid = ALC882_DIGOUT_NID,
5839 .dig_in_nid = ALC882_DIGIN_NID,
5840 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5841 .channel_mode = alc882_sixstack_modes,
5842 .input_mux = &alc882_capture_source,
5845 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5846 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5847 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5848 .dac_nids = alc882_dac_nids,
5849 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5850 .channel_mode = alc882_sixstack_modes,
5851 .input_mux = &alc882_capture_source,
5854 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5855 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5856 alc880_gpio1_init_verbs },
5857 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5858 .dac_nids = alc882_dac_nids,
5859 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5860 .channel_mode = alc880_threestack_modes,
5862 .input_mux = &alc882_capture_source,
5863 .dig_out_nid = ALC882_DIGOUT_NID,
5866 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
5867 .init_verbs = { alc885_mbp3_init_verbs,
5868 alc880_gpio1_init_verbs },
5869 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5870 .dac_nids = alc882_dac_nids,
5871 .channel_mode = alc885_mbp_6ch_modes,
5872 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
5873 .input_mux = &alc882_capture_source,
5874 .dig_out_nid = ALC882_DIGOUT_NID,
5875 .dig_in_nid = ALC882_DIGIN_NID,
5876 .unsol_event = alc885_mbp3_unsol_event,
5877 .init_hook = alc885_mbp3_automute,
5880 .mixers = { alc882_macpro_mixer },
5881 .init_verbs = { alc882_macpro_init_verbs },
5882 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5883 .dac_nids = alc882_dac_nids,
5884 .dig_out_nid = ALC882_DIGOUT_NID,
5885 .dig_in_nid = ALC882_DIGIN_NID,
5886 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5887 .channel_mode = alc882_ch_modes,
5888 .input_mux = &alc882_capture_source,
5889 .init_hook = alc885_macpro_init_hook,
5892 .mixers = { alc885_imac24_mixer },
5893 .init_verbs = { alc885_imac24_init_verbs },
5894 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5895 .dac_nids = alc882_dac_nids,
5896 .dig_out_nid = ALC882_DIGOUT_NID,
5897 .dig_in_nid = ALC882_DIGIN_NID,
5898 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5899 .channel_mode = alc882_ch_modes,
5900 .input_mux = &alc882_capture_source,
5901 .unsol_event = alc885_imac24_unsol_event,
5902 .init_hook = alc885_imac24_init_hook,
5905 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5906 alc882_capture_mixer },
5907 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5908 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5909 .dac_nids = alc882_dac_nids,
5910 .dig_out_nid = ALC882_DIGOUT_NID,
5911 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5912 .adc_nids = alc882_adc_nids,
5913 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5914 .channel_mode = alc882_3ST_6ch_modes,
5916 .input_mux = &alc882_capture_source,
5917 .unsol_event = alc882_targa_unsol_event,
5918 .init_hook = alc882_targa_automute,
5920 [ALC882_ASUS_A7J] = {
5921 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5922 alc882_capture_mixer },
5923 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5924 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5925 .dac_nids = alc882_dac_nids,
5926 .dig_out_nid = ALC882_DIGOUT_NID,
5927 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5928 .adc_nids = alc882_adc_nids,
5929 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5930 .channel_mode = alc882_3ST_6ch_modes,
5932 .input_mux = &alc882_capture_source,
5934 [ALC882_ASUS_A7M] = {
5935 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
5936 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5937 alc880_gpio1_init_verbs,
5938 alc882_asus_a7m_verbs },
5939 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5940 .dac_nids = alc882_dac_nids,
5941 .dig_out_nid = ALC882_DIGOUT_NID,
5942 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5943 .channel_mode = alc880_threestack_modes,
5945 .input_mux = &alc882_capture_source,
5954 PINFIX_ABIT_AW9D_MAX
5957 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5958 { 0x15, 0x01080104 }, /* side */
5959 { 0x16, 0x01011012 }, /* rear */
5960 { 0x17, 0x01016011 }, /* clfe */
5964 static const struct alc_pincfg *alc882_pin_fixes[] = {
5965 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5968 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5969 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5974 * BIOS auto configuration
5976 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5977 hda_nid_t nid, int pin_type,
5981 struct alc_spec *spec = codec->spec;
5984 if (spec->multiout.dac_nids[dac_idx] == 0x25)
5987 idx = spec->multiout.dac_nids[dac_idx] - 2;
5989 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5991 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5993 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5997 static void alc882_auto_init_multi_out(struct hda_codec *codec)
5999 struct alc_spec *spec = codec->spec;
6002 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6003 for (i = 0; i <= HDA_SIDE; i++) {
6004 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6005 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6007 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6012 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6014 struct alc_spec *spec = codec->spec;
6017 pin = spec->autocfg.hp_pins[0];
6018 if (pin) /* connect to front */
6020 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6023 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6024 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6026 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6028 struct alc_spec *spec = codec->spec;
6031 for (i = 0; i < AUTO_PIN_LAST; i++) {
6032 hda_nid_t nid = spec->autocfg.input_pins[i];
6033 if (alc882_is_input_pin(nid)) {
6034 snd_hda_codec_write(codec, nid, 0,
6035 AC_VERB_SET_PIN_WIDGET_CONTROL,
6036 i <= AUTO_PIN_FRONT_MIC ?
6037 PIN_VREF80 : PIN_IN);
6038 if (nid != ALC882_PIN_CD_NID)
6039 snd_hda_codec_write(codec, nid, 0,
6040 AC_VERB_SET_AMP_GAIN_MUTE,
6046 /* add mic boosts if needed */
6047 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6049 struct alc_spec *spec = codec->spec;
6053 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6055 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6057 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6061 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6063 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6065 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6072 /* almost identical with ALC880 parser... */
6073 static int alc882_parse_auto_config(struct hda_codec *codec)
6075 struct alc_spec *spec = codec->spec;
6076 int err = alc880_parse_auto_config(codec);
6081 return 0; /* no config found */
6083 err = alc_auto_add_mic_boost(codec);
6087 /* hack - override the init verbs */
6088 spec->init_verbs[0] = alc882_auto_init_verbs;
6090 return 1; /* config found */
6093 /* additional initialization for auto-configuration model */
6094 static void alc882_auto_init(struct hda_codec *codec)
6096 alc882_auto_init_multi_out(codec);
6097 alc882_auto_init_hp_out(codec);
6098 alc882_auto_init_analog_input(codec);
6101 static int patch_alc882(struct hda_codec *codec)
6103 struct alc_spec *spec;
6104 int err, board_config;
6106 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6112 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6116 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6117 /* Pick up systems that don't supply PCI SSID */
6118 switch (codec->subsystem_id) {
6119 case 0x106b0c00: /* Mac Pro */
6120 board_config = ALC885_MACPRO;
6122 case 0x106b1000: /* iMac 24 */
6123 board_config = ALC885_IMAC24;
6125 case 0x106b2c00: /* Macbook Pro rev3 */
6126 board_config = ALC885_MBP3;
6129 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6130 "trying auto-probe from BIOS...\n");
6131 board_config = ALC882_AUTO;
6135 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6137 if (board_config == ALC882_AUTO) {
6138 /* automatic parse from the BIOS config */
6139 err = alc882_parse_auto_config(codec);
6145 "hda_codec: Cannot set up configuration "
6146 "from BIOS. Using base mode...\n");
6147 board_config = ALC882_3ST_DIG;
6151 if (board_config != ALC882_AUTO)
6152 setup_preset(spec, &alc882_presets[board_config]);
6154 spec->stream_name_analog = "ALC882 Analog";
6155 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6156 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6158 spec->stream_name_digital = "ALC882 Digital";
6159 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6160 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6162 if (!spec->adc_nids && spec->input_mux) {
6163 /* check whether NID 0x07 is valid */
6164 unsigned int wcap = get_wcaps(codec, 0x07);
6166 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6167 if (wcap != AC_WID_AUD_IN) {
6168 spec->adc_nids = alc882_adc_nids_alt;
6169 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6170 spec->mixers[spec->num_mixers] =
6171 alc882_capture_alt_mixer;
6174 spec->adc_nids = alc882_adc_nids;
6175 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6176 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6181 codec->patch_ops = alc_patch_ops;
6182 if (board_config == ALC882_AUTO)
6183 spec->init_hook = alc882_auto_init;
6184 #ifdef CONFIG_SND_HDA_POWER_SAVE
6185 if (!spec->loopback.amplist)
6186 spec->loopback.amplist = alc882_loopbacks;
6195 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6196 * configuration. Each pin widget can choose any input DACs and a mixer.
6197 * Each ADC is connected from a mixer of all inputs. This makes possible
6198 * 6-channel independent captures.
6200 * In addition, an independent DAC for the multi-playback (not used in this
6203 #define ALC883_DIGOUT_NID 0x06
6204 #define ALC883_DIGIN_NID 0x0a
6206 static hda_nid_t alc883_dac_nids[4] = {
6207 /* front, rear, clfe, rear_surr */
6208 0x02, 0x04, 0x03, 0x05
6211 static hda_nid_t alc883_adc_nids[2] = {
6217 /* FIXME: should be a matrix-type input source selection */
6219 static struct hda_input_mux alc883_capture_source = {
6223 { "Front Mic", 0x1 },
6229 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6237 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6247 #define alc883_mux_enum_info alc_mux_enum_info
6248 #define alc883_mux_enum_get alc_mux_enum_get
6250 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
6251 struct snd_ctl_elem_value *ucontrol)
6253 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6254 struct alc_spec *spec = codec->spec;
6255 const struct hda_input_mux *imux = spec->input_mux;
6256 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
6257 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
6258 hda_nid_t nid = capture_mixers[adc_idx];
6259 unsigned int *cur_val = &spec->cur_mux[adc_idx];
6260 unsigned int i, idx;
6262 idx = ucontrol->value.enumerated.item[0];
6263 if (idx >= imux->num_items)
6264 idx = imux->num_items - 1;
6265 if (*cur_val == idx)
6267 for (i = 0; i < imux->num_items; i++) {
6268 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
6269 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
6270 imux->items[i].index,
6280 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6287 static struct hda_verb alc883_3ST_ch2_init[] = {
6288 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6289 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6290 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6291 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6298 static struct hda_verb alc883_3ST_ch4_init[] = {
6299 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6300 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6301 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6302 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6303 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6310 static struct hda_verb alc883_3ST_ch6_init[] = {
6311 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6312 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6313 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6314 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6315 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6316 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6320 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6321 { 2, alc883_3ST_ch2_init },
6322 { 4, alc883_3ST_ch4_init },
6323 { 6, alc883_3ST_ch6_init },
6329 static struct hda_verb alc883_sixstack_ch6_init[] = {
6330 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6331 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6332 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6333 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6340 static struct hda_verb alc883_sixstack_ch8_init[] = {
6341 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6342 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6343 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6344 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6348 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6349 { 6, alc883_sixstack_ch6_init },
6350 { 8, alc883_sixstack_ch8_init },
6353 static struct hda_verb alc883_medion_eapd_verbs[] = {
6354 /* eanable EAPD on medion laptop */
6355 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6356 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6360 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6361 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6364 static struct snd_kcontrol_new alc883_base_mixer[] = {
6365 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6366 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6367 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6368 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6369 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6370 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6371 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6372 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6373 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6374 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6375 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6376 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6377 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6378 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6379 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6380 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6381 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6382 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6383 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6384 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6385 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6386 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6387 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6388 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6389 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6390 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6391 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6393 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6394 /* .name = "Capture Source", */
6395 .name = "Input Source",
6397 .info = alc883_mux_enum_info,
6398 .get = alc883_mux_enum_get,
6399 .put = alc883_mux_enum_put,
6404 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6405 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6406 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6407 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6408 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6409 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6410 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6411 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6412 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6413 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6414 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6415 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6416 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6417 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6418 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6419 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6420 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6421 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6423 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6424 /* .name = "Capture Source", */
6425 .name = "Input Source",
6427 .info = alc883_mux_enum_info,
6428 .get = alc883_mux_enum_get,
6429 .put = alc883_mux_enum_put,
6434 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6435 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6436 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6437 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6438 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6439 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6440 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6441 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6442 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6443 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6444 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6445 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6446 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6447 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6448 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6449 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6450 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6451 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6452 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6453 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6455 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6456 /* .name = "Capture Source", */
6457 .name = "Input Source",
6459 .info = alc883_mux_enum_info,
6460 .get = alc883_mux_enum_get,
6461 .put = alc883_mux_enum_put,
6466 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6467 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6468 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6469 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6470 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6471 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6472 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6473 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6474 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6475 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6476 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6477 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6478 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6479 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6480 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6481 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6482 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6483 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6484 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6485 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6486 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6487 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6488 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6489 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6490 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6491 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6493 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6494 /* .name = "Capture Source", */
6495 .name = "Input Source",
6497 .info = alc883_mux_enum_info,
6498 .get = alc883_mux_enum_get,
6499 .put = alc883_mux_enum_put,
6504 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6505 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6506 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6507 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6508 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6509 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6510 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6511 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6512 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6513 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6514 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6515 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6516 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6517 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6518 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6519 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6520 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6521 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6522 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6523 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6524 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6525 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6526 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6527 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6530 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6531 /* .name = "Capture Source", */
6532 .name = "Input Source",
6534 .info = alc883_mux_enum_info,
6535 .get = alc883_mux_enum_get,
6536 .put = alc883_mux_enum_put,
6541 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6542 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6543 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6544 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6545 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6546 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6547 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6548 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6549 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6550 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6551 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6552 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6553 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6554 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6555 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6556 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6557 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6558 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6559 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6560 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6561 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6563 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6564 /* .name = "Capture Source", */
6565 .name = "Input Source",
6567 .info = alc883_mux_enum_info,
6568 .get = alc883_mux_enum_get,
6569 .put = alc883_mux_enum_put,
6574 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6575 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6576 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6577 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6578 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6579 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6580 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6581 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6582 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6583 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6584 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6585 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6586 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6588 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6589 /* .name = "Capture Source", */
6590 .name = "Input Source",
6592 .info = alc883_mux_enum_info,
6593 .get = alc883_mux_enum_get,
6594 .put = alc883_mux_enum_put,
6599 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6600 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6601 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6602 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6603 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6604 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6605 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6606 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6607 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6608 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6609 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6611 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6612 /* .name = "Capture Source", */
6613 .name = "Input Source",
6615 .info = alc883_mux_enum_info,
6616 .get = alc883_mux_enum_get,
6617 .put = alc883_mux_enum_put,
6622 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6623 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6624 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6625 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6626 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6627 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6628 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6629 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6630 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6631 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6632 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6633 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6634 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6635 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6637 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6638 /* .name = "Capture Source", */
6639 .name = "Input Source",
6641 .info = alc883_mux_enum_info,
6642 .get = alc883_mux_enum_get,
6643 .put = alc883_mux_enum_put,
6648 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6649 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6651 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6652 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6653 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6654 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6655 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6656 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6657 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6658 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6659 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6660 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6661 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6663 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6664 /* .name = "Capture Source", */
6665 .name = "Input Source",
6667 .info = alc883_mux_enum_info,
6668 .get = alc883_mux_enum_get,
6669 .put = alc883_mux_enum_put,
6674 static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6675 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6676 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6677 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6678 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6679 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6680 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6681 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6682 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6683 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6684 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6685 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6686 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6687 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6688 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6689 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6690 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6691 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6692 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6693 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6694 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6695 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6696 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6697 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6698 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6699 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6700 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6701 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6703 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6704 /* .name = "Capture Source", */
6705 .name = "Input Source",
6707 .info = alc883_mux_enum_info,
6708 .get = alc883_mux_enum_get,
6709 .put = alc883_mux_enum_put,
6714 static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6715 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6716 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6717 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6718 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6719 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6720 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6721 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6722 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6723 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6724 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6725 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6726 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6727 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6728 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6729 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6730 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6731 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6732 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6733 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6734 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6735 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6736 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6737 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6738 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6739 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6741 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6742 /* .name = "Capture Source", */
6743 .name = "Input Source",
6745 .info = alc883_mux_enum_info,
6746 .get = alc883_mux_enum_get,
6747 .put = alc883_mux_enum_put,
6752 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
6753 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6754 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6755 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6756 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6757 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6758 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6759 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6760 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6761 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6762 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6763 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6764 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6766 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6767 /* .name = "Capture Source", */
6768 .name = "Input Source",
6770 .info = alc883_mux_enum_info,
6771 .get = alc883_mux_enum_get,
6772 .put = alc883_mux_enum_put,
6777 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6779 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6780 .name = "Channel Mode",
6781 .info = alc_ch_mode_info,
6782 .get = alc_ch_mode_get,
6783 .put = alc_ch_mode_put,
6788 static struct hda_verb alc883_init_verbs[] = {
6789 /* ADC1: mute amp left and right */
6790 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6791 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6792 /* ADC2: mute amp left and right */
6793 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6794 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6795 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6796 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6797 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6798 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6800 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6801 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6802 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6804 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6805 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6806 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6808 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6809 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6810 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6812 /* mute analog input loopbacks */
6813 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6814 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6815 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6816 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6817 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6819 /* Front Pin: output 0 (0x0c) */
6820 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6821 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6822 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6823 /* Rear Pin: output 1 (0x0d) */
6824 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6826 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6827 /* CLFE Pin: output 2 (0x0e) */
6828 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6829 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6830 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6831 /* Side Pin: output 3 (0x0f) */
6832 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6833 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6834 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6835 /* Mic (rear) pin: input vref at 80% */
6836 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6837 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6838 /* Front Mic pin: input vref at 80% */
6839 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6840 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6841 /* Line In pin: input */
6842 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6843 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6844 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6845 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6846 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6847 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6848 /* CD pin widget for input */
6849 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6851 /* FIXME: use matrix-type input source selection */
6852 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6854 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6855 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6856 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6857 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6859 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6860 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6861 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6862 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6866 /* toggle speaker-output according to the hp-jack state */
6867 static void alc883_mitac_hp_automute(struct hda_codec *codec)
6869 unsigned int present;
6871 present = snd_hda_codec_read(codec, 0x15, 0,
6872 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6873 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6874 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6875 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
6876 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6879 /* auto-toggle front mic */
6881 static void alc883_mitac_mic_automute(struct hda_codec *codec)
6883 unsigned int present;
6886 present = snd_hda_codec_read(codec, 0x18, 0,
6887 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6888 bits = present ? HDA_AMP_MUTE : 0;
6889 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
6893 static void alc883_mitac_automute(struct hda_codec *codec)
6895 alc883_mitac_hp_automute(codec);
6896 /* alc883_mitac_mic_automute(codec); */
6899 static void alc883_mitac_unsol_event(struct hda_codec *codec,
6902 switch (res >> 26) {
6903 case ALC880_HP_EVENT:
6904 alc883_mitac_hp_automute(codec);
6906 case ALC880_MIC_EVENT:
6907 /* alc883_mitac_mic_automute(codec); */
6912 static struct hda_verb alc883_mitac_verbs[] = {
6914 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6915 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6917 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
6918 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6920 /* enable unsolicited event */
6921 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6922 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
6927 static struct hda_verb alc883_tagra_verbs[] = {
6928 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6931 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6932 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6934 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6935 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6936 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6938 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6939 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6940 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6941 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6946 static struct hda_verb alc883_lenovo_101e_verbs[] = {
6947 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6948 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6949 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6953 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6954 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6955 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6956 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6957 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6961 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6962 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6963 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6964 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6965 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6966 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6970 static struct hda_verb alc883_haier_w66_verbs[] = {
6971 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6974 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6976 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6977 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6978 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6979 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6983 static struct hda_verb alc888_6st_hp_verbs[] = {
6984 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
6985 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */
6986 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */
6987 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
6991 static struct hda_verb alc888_3st_hp_verbs[] = {
6992 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
6993 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
6994 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
6998 static struct hda_verb alc888_3st_hp_2ch_init[] = {
6999 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7000 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7001 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7002 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7006 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7007 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7008 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7009 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7010 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7014 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7015 { 2, alc888_3st_hp_2ch_init },
7016 { 6, alc888_3st_hp_6ch_init },
7019 /* toggle front-jack and RCA according to the hp-jack state */
7020 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7022 unsigned int present;
7024 present = snd_hda_codec_read(codec, 0x1b, 0,
7025 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7026 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7027 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7028 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7029 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7032 /* toggle RCA according to the front-jack state */
7033 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7035 unsigned int present;
7037 present = snd_hda_codec_read(codec, 0x14, 0,
7038 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7039 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7040 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7043 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7046 if ((res >> 26) == ALC880_HP_EVENT)
7047 alc888_lenovo_ms7195_front_automute(codec);
7048 if ((res >> 26) == ALC880_FRONT_EVENT)
7049 alc888_lenovo_ms7195_rca_automute(codec);
7052 static struct hda_verb alc883_medion_md2_verbs[] = {
7053 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7054 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7056 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7058 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7062 /* toggle speaker-output according to the hp-jack state */
7063 static void alc883_medion_md2_automute(struct hda_codec *codec)
7065 unsigned int present;
7067 present = snd_hda_codec_read(codec, 0x14, 0,
7068 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7069 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7070 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7073 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7076 if ((res >> 26) == ALC880_HP_EVENT)
7077 alc883_medion_md2_automute(codec);
7080 /* toggle speaker-output according to the hp-jack state */
7081 static void alc883_tagra_automute(struct hda_codec *codec)
7083 unsigned int present;
7086 present = snd_hda_codec_read(codec, 0x14, 0,
7087 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7088 bits = present ? HDA_AMP_MUTE : 0;
7089 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7090 HDA_AMP_MUTE, bits);
7091 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7095 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7097 if ((res >> 26) == ALC880_HP_EVENT)
7098 alc883_tagra_automute(codec);
7101 static void alc883_haier_w66_automute(struct hda_codec *codec)
7103 unsigned int present;
7106 present = snd_hda_codec_read(codec, 0x1b, 0,
7107 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7108 bits = present ? 0x80 : 0;
7109 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7113 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7116 if ((res >> 26) == ALC880_HP_EVENT)
7117 alc883_haier_w66_automute(codec);
7120 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7122 unsigned int present;
7125 present = snd_hda_codec_read(codec, 0x14, 0,
7126 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7127 bits = present ? HDA_AMP_MUTE : 0;
7128 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7129 HDA_AMP_MUTE, bits);
7132 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7134 unsigned int present;
7137 present = snd_hda_codec_read(codec, 0x1b, 0,
7138 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7139 bits = present ? HDA_AMP_MUTE : 0;
7140 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7141 HDA_AMP_MUTE, bits);
7142 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7143 HDA_AMP_MUTE, bits);
7146 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7149 if ((res >> 26) == ALC880_HP_EVENT)
7150 alc883_lenovo_101e_all_automute(codec);
7151 if ((res >> 26) == ALC880_FRONT_EVENT)
7152 alc883_lenovo_101e_ispeaker_automute(codec);
7155 /* toggle speaker-output according to the hp-jack state */
7156 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7158 unsigned int present;
7160 present = snd_hda_codec_read(codec, 0x14, 0,
7161 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7162 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7163 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7164 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7165 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7168 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7171 if ((res >> 26) == ALC880_HP_EVENT)
7172 alc883_acer_aspire_automute(codec);
7175 static struct hda_verb alc883_acer_eapd_verbs[] = {
7176 /* HP Pin: output 0 (0x0c) */
7177 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7178 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7179 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7180 /* Front Pin: output 0 (0x0c) */
7181 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7182 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7183 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7184 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7185 /* eanable EAPD on medion laptop */
7186 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7187 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7188 /* enable unsolicited event */
7189 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7194 * generic initialization of ADC, input mixers and output mixers
7196 static struct hda_verb alc883_auto_init_verbs[] = {
7198 * Unmute ADC0-2 and set the default input to mic-in
7200 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7201 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7202 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7203 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7205 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7207 * Note: PASD motherboards uses the Line In 2 as the input for
7208 * front panel mic (mic 2)
7210 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7213 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7214 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7215 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7218 * Set up output mixers (0x0c - 0x0f)
7220 /* set vol=0 to output mixers */
7221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7222 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7223 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7224 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7225 /* set up input amps for analog loopback */
7226 /* Amp Indices: DAC = 0, mixer = 1 */
7227 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7229 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7230 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7231 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7232 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7233 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7234 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7235 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7236 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7238 /* FIXME: use matrix-type input source selection */
7239 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7241 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7242 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7243 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7244 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7245 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7247 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7248 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7249 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7250 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7251 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7256 /* capture mixer elements */
7257 static struct snd_kcontrol_new alc883_capture_mixer[] = {
7258 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7259 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7260 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7261 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7263 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7264 /* The multiple "Capture Source" controls confuse alsamixer
7265 * So call somewhat different..
7266 * FIXME: the controls appear in the "playback" view!
7268 /* .name = "Capture Source", */
7269 .name = "Input Source",
7271 .info = alc882_mux_enum_info,
7272 .get = alc882_mux_enum_get,
7273 .put = alc882_mux_enum_put,
7278 #ifdef CONFIG_SND_HDA_POWER_SAVE
7279 #define alc883_loopbacks alc880_loopbacks
7282 /* pcm configuration: identiacal with ALC880 */
7283 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
7284 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
7285 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
7286 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
7289 * configuration and preset
7291 static const char *alc883_models[ALC883_MODEL_LAST] = {
7292 [ALC883_3ST_2ch_DIG] = "3stack-dig",
7293 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
7294 [ALC883_3ST_6ch] = "3stack-6ch",
7295 [ALC883_6ST_DIG] = "6stack-dig",
7296 [ALC883_TARGA_DIG] = "targa-dig",
7297 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
7298 [ALC883_ACER] = "acer",
7299 [ALC883_ACER_ASPIRE] = "acer-aspire",
7300 [ALC883_MEDION] = "medion",
7301 [ALC883_MEDION_MD2] = "medion-md2",
7302 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
7303 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
7304 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
7305 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
7306 [ALC883_HAIER_W66] = "haier-w66",
7307 [ALC888_6ST_HP] = "6stack-hp",
7308 [ALC888_3ST_HP] = "3stack-hp",
7309 [ALC883_MITAC] = "mitac",
7310 [ALC883_AUTO] = "auto",
7313 static struct snd_pci_quirk alc883_cfg_tbl[] = {
7314 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
7315 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7316 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7317 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7318 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
7319 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
7320 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7321 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7322 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7323 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
7324 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
7325 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7326 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7327 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
7328 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
7329 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
7330 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
7331 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
7332 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
7333 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
7334 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
7335 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7336 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
7337 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
7338 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
7339 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7340 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7341 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
7342 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7343 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7344 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7345 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7346 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
7347 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
7348 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7349 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
7350 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
7351 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
7352 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
7353 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7354 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7355 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7356 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7357 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
7358 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
7362 static struct alc_config_preset alc883_presets[] = {
7363 [ALC883_3ST_2ch_DIG] = {
7364 .mixers = { alc883_3ST_2ch_mixer },
7365 .init_verbs = { alc883_init_verbs },
7366 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7367 .dac_nids = alc883_dac_nids,
7368 .dig_out_nid = ALC883_DIGOUT_NID,
7369 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7370 .adc_nids = alc883_adc_nids,
7371 .dig_in_nid = ALC883_DIGIN_NID,
7372 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7373 .channel_mode = alc883_3ST_2ch_modes,
7374 .input_mux = &alc883_capture_source,
7376 [ALC883_3ST_6ch_DIG] = {
7377 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7378 .init_verbs = { alc883_init_verbs },
7379 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7380 .dac_nids = alc883_dac_nids,
7381 .dig_out_nid = ALC883_DIGOUT_NID,
7382 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7383 .adc_nids = alc883_adc_nids,
7384 .dig_in_nid = ALC883_DIGIN_NID,
7385 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7386 .channel_mode = alc883_3ST_6ch_modes,
7388 .input_mux = &alc883_capture_source,
7390 [ALC883_3ST_6ch] = {
7391 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7392 .init_verbs = { alc883_init_verbs },
7393 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7394 .dac_nids = alc883_dac_nids,
7395 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7396 .adc_nids = alc883_adc_nids,
7397 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7398 .channel_mode = alc883_3ST_6ch_modes,
7400 .input_mux = &alc883_capture_source,
7402 [ALC883_6ST_DIG] = {
7403 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7404 .init_verbs = { alc883_init_verbs },
7405 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7406 .dac_nids = alc883_dac_nids,
7407 .dig_out_nid = ALC883_DIGOUT_NID,
7408 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7409 .adc_nids = alc883_adc_nids,
7410 .dig_in_nid = ALC883_DIGIN_NID,
7411 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7412 .channel_mode = alc883_sixstack_modes,
7413 .input_mux = &alc883_capture_source,
7415 [ALC883_TARGA_DIG] = {
7416 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7417 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7418 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7419 .dac_nids = alc883_dac_nids,
7420 .dig_out_nid = ALC883_DIGOUT_NID,
7421 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7422 .adc_nids = alc883_adc_nids,
7423 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7424 .channel_mode = alc883_3ST_6ch_modes,
7426 .input_mux = &alc883_capture_source,
7427 .unsol_event = alc883_tagra_unsol_event,
7428 .init_hook = alc883_tagra_automute,
7430 [ALC883_TARGA_2ch_DIG] = {
7431 .mixers = { alc883_tagra_2ch_mixer},
7432 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7433 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7434 .dac_nids = alc883_dac_nids,
7435 .dig_out_nid = ALC883_DIGOUT_NID,
7436 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7437 .adc_nids = alc883_adc_nids,
7438 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7439 .channel_mode = alc883_3ST_2ch_modes,
7440 .input_mux = &alc883_capture_source,
7441 .unsol_event = alc883_tagra_unsol_event,
7442 .init_hook = alc883_tagra_automute,
7445 .mixers = { alc883_base_mixer },
7446 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7447 * and the headphone jack. Turn this on and rely on the
7448 * standard mute methods whenever the user wants to turn
7449 * these outputs off.
7451 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7452 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7453 .dac_nids = alc883_dac_nids,
7454 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7455 .adc_nids = alc883_adc_nids,
7456 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7457 .channel_mode = alc883_3ST_2ch_modes,
7458 .input_mux = &alc883_capture_source,
7460 [ALC883_ACER_ASPIRE] = {
7461 .mixers = { alc883_acer_aspire_mixer },
7462 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
7463 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7464 .dac_nids = alc883_dac_nids,
7465 .dig_out_nid = ALC883_DIGOUT_NID,
7466 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7467 .adc_nids = alc883_adc_nids,
7468 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7469 .channel_mode = alc883_3ST_2ch_modes,
7470 .input_mux = &alc883_capture_source,
7471 .unsol_event = alc883_acer_aspire_unsol_event,
7472 .init_hook = alc883_acer_aspire_automute,
7475 .mixers = { alc883_fivestack_mixer,
7476 alc883_chmode_mixer },
7477 .init_verbs = { alc883_init_verbs,
7478 alc883_medion_eapd_verbs },
7479 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7480 .dac_nids = alc883_dac_nids,
7481 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7482 .adc_nids = alc883_adc_nids,
7483 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7484 .channel_mode = alc883_sixstack_modes,
7485 .input_mux = &alc883_capture_source,
7487 [ALC883_MEDION_MD2] = {
7488 .mixers = { alc883_medion_md2_mixer},
7489 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7490 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7491 .dac_nids = alc883_dac_nids,
7492 .dig_out_nid = ALC883_DIGOUT_NID,
7493 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7494 .adc_nids = alc883_adc_nids,
7495 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7496 .channel_mode = alc883_3ST_2ch_modes,
7497 .input_mux = &alc883_capture_source,
7498 .unsol_event = alc883_medion_md2_unsol_event,
7499 .init_hook = alc883_medion_md2_automute,
7501 [ALC883_LAPTOP_EAPD] = {
7502 .mixers = { alc883_base_mixer },
7503 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7504 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7505 .dac_nids = alc883_dac_nids,
7506 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7507 .adc_nids = alc883_adc_nids,
7508 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7509 .channel_mode = alc883_3ST_2ch_modes,
7510 .input_mux = &alc883_capture_source,
7512 [ALC883_LENOVO_101E_2ch] = {
7513 .mixers = { alc883_lenovo_101e_2ch_mixer},
7514 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7515 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7516 .dac_nids = alc883_dac_nids,
7517 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7518 .adc_nids = alc883_adc_nids,
7519 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7520 .channel_mode = alc883_3ST_2ch_modes,
7521 .input_mux = &alc883_lenovo_101e_capture_source,
7522 .unsol_event = alc883_lenovo_101e_unsol_event,
7523 .init_hook = alc883_lenovo_101e_all_automute,
7525 [ALC883_LENOVO_NB0763] = {
7526 .mixers = { alc883_lenovo_nb0763_mixer },
7527 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7528 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7529 .dac_nids = alc883_dac_nids,
7530 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7531 .adc_nids = alc883_adc_nids,
7532 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7533 .channel_mode = alc883_3ST_2ch_modes,
7535 .input_mux = &alc883_lenovo_nb0763_capture_source,
7536 .unsol_event = alc883_medion_md2_unsol_event,
7537 .init_hook = alc883_medion_md2_automute,
7539 [ALC888_LENOVO_MS7195_DIG] = {
7540 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7541 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7542 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7543 .dac_nids = alc883_dac_nids,
7544 .dig_out_nid = ALC883_DIGOUT_NID,
7545 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7546 .adc_nids = alc883_adc_nids,
7547 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7548 .channel_mode = alc883_3ST_6ch_modes,
7550 .input_mux = &alc883_capture_source,
7551 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7552 .init_hook = alc888_lenovo_ms7195_front_automute,
7554 [ALC883_HAIER_W66] = {
7555 .mixers = { alc883_tagra_2ch_mixer},
7556 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7557 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7558 .dac_nids = alc883_dac_nids,
7559 .dig_out_nid = ALC883_DIGOUT_NID,
7560 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7561 .adc_nids = alc883_adc_nids,
7562 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7563 .channel_mode = alc883_3ST_2ch_modes,
7564 .input_mux = &alc883_capture_source,
7565 .unsol_event = alc883_haier_w66_unsol_event,
7566 .init_hook = alc883_haier_w66_automute,
7569 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7570 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
7571 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7572 .dac_nids = alc883_dac_nids,
7573 .dig_out_nid = ALC883_DIGOUT_NID,
7574 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7575 .adc_nids = alc883_adc_nids,
7576 .dig_in_nid = ALC883_DIGIN_NID,
7577 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7578 .channel_mode = alc883_sixstack_modes,
7579 .input_mux = &alc883_capture_source,
7582 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7583 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
7584 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7585 .dac_nids = alc883_dac_nids,
7586 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7587 .adc_nids = alc883_adc_nids,
7588 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7589 .channel_mode = alc888_3st_hp_modes,
7591 .input_mux = &alc883_capture_source,
7594 .mixers = { alc883_mitac_mixer },
7595 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
7596 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7597 .dac_nids = alc883_dac_nids,
7598 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7599 .adc_nids = alc883_adc_nids,
7600 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7601 .channel_mode = alc883_3ST_2ch_modes,
7602 .input_mux = &alc883_capture_source,
7603 .unsol_event = alc883_mitac_unsol_event,
7604 .init_hook = alc883_mitac_automute,
7610 * BIOS auto configuration
7612 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7613 hda_nid_t nid, int pin_type,
7617 struct alc_spec *spec = codec->spec;
7620 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7623 idx = spec->multiout.dac_nids[dac_idx] - 2;
7625 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7627 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7629 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7633 static void alc883_auto_init_multi_out(struct hda_codec *codec)
7635 struct alc_spec *spec = codec->spec;
7638 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7639 for (i = 0; i <= HDA_SIDE; i++) {
7640 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7641 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7643 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
7648 static void alc883_auto_init_hp_out(struct hda_codec *codec)
7650 struct alc_spec *spec = codec->spec;
7653 pin = spec->autocfg.hp_pins[0];
7654 if (pin) /* connect to front */
7656 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7659 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
7660 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
7662 static void alc883_auto_init_analog_input(struct hda_codec *codec)
7664 struct alc_spec *spec = codec->spec;
7667 for (i = 0; i < AUTO_PIN_LAST; i++) {
7668 hda_nid_t nid = spec->autocfg.input_pins[i];
7669 if (alc883_is_input_pin(nid)) {
7670 snd_hda_codec_write(codec, nid, 0,
7671 AC_VERB_SET_PIN_WIDGET_CONTROL,
7672 (i <= AUTO_PIN_FRONT_MIC ?
7673 PIN_VREF80 : PIN_IN));
7674 if (nid != ALC883_PIN_CD_NID)
7675 snd_hda_codec_write(codec, nid, 0,
7676 AC_VERB_SET_AMP_GAIN_MUTE,
7682 /* almost identical with ALC880 parser... */
7683 static int alc883_parse_auto_config(struct hda_codec *codec)
7685 struct alc_spec *spec = codec->spec;
7686 int err = alc880_parse_auto_config(codec);
7691 return 0; /* no config found */
7693 err = alc_auto_add_mic_boost(codec);
7697 /* hack - override the init verbs */
7698 spec->init_verbs[0] = alc883_auto_init_verbs;
7699 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7702 return 1; /* config found */
7705 /* additional initialization for auto-configuration model */
7706 static void alc883_auto_init(struct hda_codec *codec)
7708 alc883_auto_init_multi_out(codec);
7709 alc883_auto_init_hp_out(codec);
7710 alc883_auto_init_analog_input(codec);
7713 static int patch_alc883(struct hda_codec *codec)
7715 struct alc_spec *spec;
7716 int err, board_config;
7718 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7724 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7727 if (board_config < 0) {
7728 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7729 "trying auto-probe from BIOS...\n");
7730 board_config = ALC883_AUTO;
7733 if (board_config == ALC883_AUTO) {
7734 /* automatic parse from the BIOS config */
7735 err = alc883_parse_auto_config(codec);
7741 "hda_codec: Cannot set up configuration "
7742 "from BIOS. Using base mode...\n");
7743 board_config = ALC883_3ST_2ch_DIG;
7747 if (board_config != ALC883_AUTO)
7748 setup_preset(spec, &alc883_presets[board_config]);
7750 spec->stream_name_analog = "ALC883 Analog";
7751 spec->stream_analog_playback = &alc883_pcm_analog_playback;
7752 spec->stream_analog_capture = &alc883_pcm_analog_capture;
7754 spec->stream_name_digital = "ALC883 Digital";
7755 spec->stream_digital_playback = &alc883_pcm_digital_playback;
7756 spec->stream_digital_capture = &alc883_pcm_digital_capture;
7758 if (!spec->adc_nids && spec->input_mux) {
7759 spec->adc_nids = alc883_adc_nids;
7760 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7763 codec->patch_ops = alc_patch_ops;
7764 if (board_config == ALC883_AUTO)
7765 spec->init_hook = alc883_auto_init;
7766 #ifdef CONFIG_SND_HDA_POWER_SAVE
7767 if (!spec->loopback.amplist)
7768 spec->loopback.amplist = alc883_loopbacks;
7778 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
7779 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
7781 #define alc262_dac_nids alc260_dac_nids
7782 #define alc262_adc_nids alc882_adc_nids
7783 #define alc262_adc_nids_alt alc882_adc_nids_alt
7785 #define alc262_modes alc260_modes
7786 #define alc262_capture_source alc882_capture_source
7788 static struct snd_kcontrol_new alc262_base_mixer[] = {
7789 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7790 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7791 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7792 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7793 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7794 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7796 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7797 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7798 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7799 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7800 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7801 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7802 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7803 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7804 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7805 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7806 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7810 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7811 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7812 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7813 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7814 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7815 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7816 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7817 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7818 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7819 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7820 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7821 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7822 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7823 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7824 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7825 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7826 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7830 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7831 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7832 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7833 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7834 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7835 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7837 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7838 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7839 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7840 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7841 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7842 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7843 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7844 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7845 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7846 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7847 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7848 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7849 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7850 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7854 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7855 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7856 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7857 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7858 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7859 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7860 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7861 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7862 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7863 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7864 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7865 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7866 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7867 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7868 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7869 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7873 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7874 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7875 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7876 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7880 static struct hda_bind_ctls alc262_hp_t5735_bind_front_vol = {
7881 .ops = &snd_hda_bind_vol,
7883 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7884 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
7889 static struct hda_bind_ctls alc262_hp_t5735_bind_front_sw = {
7890 .ops = &snd_hda_bind_sw,
7892 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7893 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7898 /* mute/unmute internal speaker according to the hp jack and mute state */
7899 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
7901 struct alc_spec *spec = codec->spec;
7904 if (force || !spec->sense_updated) {
7905 unsigned int present;
7906 present = snd_hda_codec_read(codec, 0x15, 0,
7907 AC_VERB_GET_PIN_SENSE, 0);
7908 spec->jack_present = (present & 0x80000000) != 0;
7909 spec->sense_updated = 1;
7911 if (spec->jack_present)
7912 mute = (0x7080 | ((0)<<8)); /* mute internal speaker */
7913 else /* unmute internal speaker if necessary */
7914 mute = (0x7000 | ((0)<<8));
7915 snd_hda_codec_write(codec, 0x0c, 0,
7916 AC_VERB_SET_AMP_GAIN_MUTE, mute );
7919 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
7922 if ((res >> 26) != ALC880_HP_EVENT)
7924 alc262_hp_t5735_automute(codec, 1);
7927 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
7929 alc262_hp_t5735_automute(codec, 1);
7932 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
7933 HDA_BIND_VOL("PCM Playback Volume", &alc262_hp_t5735_bind_front_vol),
7934 HDA_BIND_SW("PCM Playback Switch",&alc262_hp_t5735_bind_front_sw),
7935 HDA_CODEC_VOLUME("LineOut Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7936 HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7937 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7938 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7939 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7940 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7941 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7942 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7943 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7947 static struct hda_verb alc262_hp_t5735_verbs[] = {
7948 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7949 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7951 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7955 /* bind hp and internal speaker mute (with plug check) */
7956 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
7957 struct snd_ctl_elem_value *ucontrol)
7959 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7960 long *valp = ucontrol->value.integer.value;
7963 /* change hp mute */
7964 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7966 valp[0] ? 0 : HDA_AMP_MUTE);
7967 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7969 valp[1] ? 0 : HDA_AMP_MUTE);
7971 /* change speaker according to HP jack state */
7972 struct alc_spec *spec = codec->spec;
7974 if (spec->jack_present)
7975 mute = HDA_AMP_MUTE;
7977 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
7979 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7980 HDA_AMP_MUTE, mute);
7985 static struct snd_kcontrol_new alc262_sony_mixer[] = {
7986 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7988 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7989 .name = "Master Playback Switch",
7990 .info = snd_hda_mixer_amp_switch_info,
7991 .get = snd_hda_mixer_amp_switch_get,
7992 .put = alc262_sony_master_sw_put,
7993 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7997 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7998 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8002 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8003 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8004 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8005 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8006 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8007 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8008 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8009 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8013 #define alc262_capture_mixer alc882_capture_mixer
8014 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
8017 * generic initialization of ADC, input mixers and output mixers
8019 static struct hda_verb alc262_init_verbs[] = {
8021 * Unmute ADC0-2 and set the default input to mic-in
8023 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8024 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8025 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8026 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8027 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8028 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8030 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8032 * Note: PASD motherboards uses the Line In 2 as the input for
8033 * front panel mic (mic 2)
8035 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8036 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8037 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8038 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8039 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8040 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8043 * Set up output mixers (0x0c - 0x0e)
8045 /* set vol=0 to output mixers */
8046 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8047 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8048 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8049 /* set up input amps for analog loopback */
8050 /* Amp Indices: DAC = 0, mixer = 1 */
8051 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8052 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8053 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8054 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8055 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8056 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8058 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8059 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8060 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8061 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8062 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8063 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8065 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8066 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8067 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8068 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8069 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8071 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8072 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8074 /* FIXME: use matrix-type input source selection */
8075 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8076 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8077 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8078 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8079 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8080 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8082 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8083 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8084 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8085 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8088 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8089 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8090 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8095 static struct hda_verb alc262_hippo_unsol_verbs[] = {
8096 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8097 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8101 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8102 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8103 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8104 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8106 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8107 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8111 static struct hda_verb alc262_sony_unsol_verbs[] = {
8112 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8113 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8114 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
8116 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8117 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8120 /* mute/unmute internal speaker according to the hp jack and mute state */
8121 static void alc262_hippo_automute(struct hda_codec *codec)
8123 struct alc_spec *spec = codec->spec;
8125 unsigned int present;
8127 /* need to execute and sync at first */
8128 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8129 present = snd_hda_codec_read(codec, 0x15, 0,
8130 AC_VERB_GET_PIN_SENSE, 0);
8131 spec->jack_present = (present & 0x80000000) != 0;
8132 if (spec->jack_present) {
8133 /* mute internal speaker */
8134 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8135 HDA_AMP_MUTE, HDA_AMP_MUTE);
8137 /* unmute internal speaker if necessary */
8138 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8139 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8140 HDA_AMP_MUTE, mute);
8144 /* unsolicited event for HP jack sensing */
8145 static void alc262_hippo_unsol_event(struct hda_codec *codec,
8148 if ((res >> 26) != ALC880_HP_EVENT)
8150 alc262_hippo_automute(codec);
8153 static void alc262_hippo1_automute(struct hda_codec *codec)
8156 unsigned int present;
8158 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8159 present = snd_hda_codec_read(codec, 0x1b, 0,
8160 AC_VERB_GET_PIN_SENSE, 0);
8161 present = (present & 0x80000000) != 0;
8163 /* mute internal speaker */
8164 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8165 HDA_AMP_MUTE, HDA_AMP_MUTE);
8167 /* unmute internal speaker if necessary */
8168 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8169 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8170 HDA_AMP_MUTE, mute);
8174 /* unsolicited event for HP jack sensing */
8175 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8178 if ((res >> 26) != ALC880_HP_EVENT)
8180 alc262_hippo1_automute(codec);
8185 * 0x14 = headphone/spdif-out, 0x15 = internal speaker
8188 #define ALC_HP_EVENT 0x37
8190 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8191 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8192 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8196 static struct hda_input_mux alc262_fujitsu_capture_source = {
8205 static struct hda_input_mux alc262_HP_capture_source = {
8209 { "Front Mic", 0x1 },
8216 static struct hda_input_mux alc262_HP_D7000_capture_source = {
8220 { "Front Mic", 0x2 },
8226 /* mute/unmute internal speaker according to the hp jack and mute state */
8227 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8229 struct alc_spec *spec = codec->spec;
8232 if (force || !spec->sense_updated) {
8233 unsigned int present;
8234 /* need to execute and sync at first */
8235 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8236 present = snd_hda_codec_read(codec, 0x14, 0,
8237 AC_VERB_GET_PIN_SENSE, 0);
8238 spec->jack_present = (present & 0x80000000) != 0;
8239 spec->sense_updated = 1;
8241 if (spec->jack_present) {
8242 /* mute internal speaker */
8243 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8244 HDA_AMP_MUTE, HDA_AMP_MUTE);
8246 /* unmute internal speaker if necessary */
8247 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8248 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8249 HDA_AMP_MUTE, mute);
8253 /* unsolicited event for HP jack sensing */
8254 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8257 if ((res >> 26) != ALC_HP_EVENT)
8259 alc262_fujitsu_automute(codec, 1);
8262 /* bind volumes of both NID 0x0c and 0x0d */
8263 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8264 .ops = &snd_hda_bind_vol,
8266 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8267 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8272 /* bind hp and internal speaker mute (with plug check) */
8273 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8274 struct snd_ctl_elem_value *ucontrol)
8276 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8277 long *valp = ucontrol->value.integer.value;
8280 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
8282 valp[0] ? 0 : HDA_AMP_MUTE);
8283 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
8285 valp[1] ? 0 : HDA_AMP_MUTE);
8287 alc262_fujitsu_automute(codec, 0);
8291 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
8292 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
8294 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8295 .name = "Master Playback Switch",
8296 .info = snd_hda_mixer_amp_switch_info,
8297 .get = snd_hda_mixer_amp_switch_get,
8298 .put = alc262_fujitsu_master_sw_put,
8299 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8301 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8302 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8303 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8305 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8306 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8307 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8308 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8312 /* additional init verbs for Benq laptops */
8313 static struct hda_verb alc262_EAPD_verbs[] = {
8314 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8315 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8319 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8320 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8321 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8323 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8324 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8328 /* Samsung Q1 Ultra Vista model setup */
8329 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8330 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8331 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8332 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8333 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8334 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8335 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8339 static struct hda_verb alc262_ultra_verbs[] = {
8340 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8341 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8342 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8343 /* Mic is on Node 0x19 */
8344 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8345 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
8346 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8347 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
8348 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8349 {0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
8350 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8354 static struct hda_input_mux alc262_ultra_capture_source = {
8361 /* mute/unmute internal speaker according to the hp jack and mute state */
8362 static void alc262_ultra_automute(struct hda_codec *codec)
8364 struct alc_spec *spec = codec->spec;
8366 unsigned int present;
8368 /* need to execute and sync at first */
8369 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8370 present = snd_hda_codec_read(codec, 0x15, 0,
8371 AC_VERB_GET_PIN_SENSE, 0);
8372 spec->jack_present = (present & 0x80000000) != 0;
8373 if (spec->jack_present) {
8374 /* mute internal speaker */
8375 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8376 HDA_AMP_MUTE, HDA_AMP_MUTE);
8378 /* unmute internal speaker if necessary */
8379 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8380 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8381 HDA_AMP_MUTE, mute);
8385 /* unsolicited event for HP jack sensing */
8386 static void alc262_ultra_unsol_event(struct hda_codec *codec,
8389 if ((res >> 26) != ALC880_HP_EVENT)
8391 alc262_ultra_automute(codec);
8394 /* add playback controls from the parsed DAC table */
8395 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8396 const struct auto_pin_cfg *cfg)
8401 spec->multiout.num_dacs = 1; /* only use one dac */
8402 spec->multiout.dac_nids = spec->private_dac_nids;
8403 spec->multiout.dac_nids[0] = 2;
8405 nid = cfg->line_out_pins[0];
8407 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8408 "Front Playback Volume",
8409 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8412 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8413 "Front Playback Switch",
8414 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8419 nid = cfg->speaker_pins[0];
8422 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8423 "Speaker Playback Volume",
8424 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8428 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8429 "Speaker Playback Switch",
8430 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8435 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8436 "Speaker Playback Switch",
8437 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8443 nid = cfg->hp_pins[0];
8445 /* spec->multiout.hp_nid = 2; */
8447 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8448 "Headphone Playback Volume",
8449 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8453 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8454 "Headphone Playback Switch",
8455 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8460 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8461 "Headphone Playback Switch",
8462 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8471 /* identical with ALC880 */
8472 #define alc262_auto_create_analog_input_ctls \
8473 alc880_auto_create_analog_input_ctls
8476 * generic initialization of ADC, input mixers and output mixers
8478 static struct hda_verb alc262_volume_init_verbs[] = {
8480 * Unmute ADC0-2 and set the default input to mic-in
8482 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8483 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8484 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8486 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8487 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8489 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8491 * Note: PASD motherboards uses the Line In 2 as the input for
8492 * front panel mic (mic 2)
8494 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8495 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8496 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8497 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8498 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8499 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8502 * Set up output mixers (0x0c - 0x0f)
8504 /* set vol=0 to output mixers */
8505 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8509 /* set up input amps for analog loopback */
8510 /* Amp Indices: DAC = 0, mixer = 1 */
8511 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8515 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8518 /* FIXME: use matrix-type input source selection */
8519 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8520 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8523 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8524 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8528 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8529 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8539 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8541 * Unmute ADC0-2 and set the default input to mic-in
8543 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8544 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8545 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8546 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8547 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8548 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8550 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8552 * Note: PASD motherboards uses the Line In 2 as the input for
8553 * front panel mic (mic 2)
8555 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8556 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8557 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8558 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8559 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8560 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8561 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8562 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8565 * Set up output mixers (0x0c - 0x0e)
8567 /* set vol=0 to output mixers */
8568 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8569 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8570 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8572 /* set up input amps for analog loopback */
8573 /* Amp Indices: DAC = 0, mixer = 1 */
8574 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8575 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8576 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8577 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8578 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8579 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8581 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8582 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8583 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8585 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8586 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8588 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8589 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8591 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8592 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8593 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8594 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8595 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8597 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8598 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8599 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8600 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8601 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8602 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8605 /* FIXME: use matrix-type input source selection */
8606 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8607 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8609 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8610 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8611 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8614 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8615 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8616 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8621 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8626 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
8628 * Unmute ADC0-2 and set the default input to mic-in
8630 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8631 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8632 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8633 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8634 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8635 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8637 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8639 * Note: PASD motherboards uses the Line In 2 as the input for front
8642 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8643 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8644 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8645 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8646 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8647 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8648 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8649 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8650 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
8652 * Set up output mixers (0x0c - 0x0e)
8654 /* set vol=0 to output mixers */
8655 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8656 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8657 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8659 /* set up input amps for analog loopback */
8660 /* Amp Indices: DAC = 0, mixer = 1 */
8661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8662 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8663 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8664 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8665 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8666 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8669 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
8670 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
8671 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
8672 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
8673 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
8674 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
8675 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
8677 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8678 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8680 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8681 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8683 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
8684 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8685 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8686 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8687 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8688 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8690 /* FIXME: use matrix-type input source selection */
8691 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8692 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8693 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
8694 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
8695 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
8696 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
8697 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
8698 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8699 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
8701 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8702 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8703 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8704 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8705 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8706 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8707 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8709 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8710 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8711 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8712 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8713 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8714 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8715 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8720 #ifdef CONFIG_SND_HDA_POWER_SAVE
8721 #define alc262_loopbacks alc880_loopbacks
8724 /* pcm configuration: identiacal with ALC880 */
8725 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
8726 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
8727 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
8728 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
8731 * BIOS auto configuration
8733 static int alc262_parse_auto_config(struct hda_codec *codec)
8735 struct alc_spec *spec = codec->spec;
8737 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
8739 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8743 if (!spec->autocfg.line_outs)
8744 return 0; /* can't find valid BIOS pin config */
8745 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
8748 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
8752 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
8754 if (spec->autocfg.dig_out_pin)
8755 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
8756 if (spec->autocfg.dig_in_pin)
8757 spec->dig_in_nid = ALC262_DIGIN_NID;
8759 if (spec->kctl_alloc)
8760 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8762 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
8763 spec->num_mux_defs = 1;
8764 spec->input_mux = &spec->private_imux;
8766 err = alc_auto_add_mic_boost(codec);
8773 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
8774 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
8775 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
8778 /* init callback for auto-configuration model -- overriding the default init */
8779 static void alc262_auto_init(struct hda_codec *codec)
8781 alc262_auto_init_multi_out(codec);
8782 alc262_auto_init_hp_out(codec);
8783 alc262_auto_init_analog_input(codec);
8787 * configuration and preset
8789 static const char *alc262_models[ALC262_MODEL_LAST] = {
8790 [ALC262_BASIC] = "basic",
8791 [ALC262_HIPPO] = "hippo",
8792 [ALC262_HIPPO_1] = "hippo_1",
8793 [ALC262_FUJITSU] = "fujitsu",
8794 [ALC262_HP_BPC] = "hp-bpc",
8795 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
8796 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8797 [ALC262_BENQ_ED8] = "benq",
8798 [ALC262_BENQ_T31] = "benq-t31",
8799 [ALC262_SONY_ASSAMD] = "sony-assamd",
8800 [ALC262_ULTRA] = "ultra",
8801 [ALC262_AUTO] = "auto",
8804 static struct snd_pci_quirk alc262_cfg_tbl[] = {
8805 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
8806 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
8807 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
8808 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
8809 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
8810 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
8811 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
8812 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
8813 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
8814 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
8815 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
8816 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
8817 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
8818 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
8819 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
8820 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
8821 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
8822 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
8823 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
8824 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
8825 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
8826 ALC262_HP_TC_T5735),
8827 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8828 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
8829 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8830 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8831 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
8832 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
8833 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
8834 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
8835 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
8836 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
8840 static struct alc_config_preset alc262_presets[] = {
8842 .mixers = { alc262_base_mixer },
8843 .init_verbs = { alc262_init_verbs },
8844 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8845 .dac_nids = alc262_dac_nids,
8847 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8848 .channel_mode = alc262_modes,
8849 .input_mux = &alc262_capture_source,
8852 .mixers = { alc262_base_mixer },
8853 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
8854 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8855 .dac_nids = alc262_dac_nids,
8857 .dig_out_nid = ALC262_DIGOUT_NID,
8858 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8859 .channel_mode = alc262_modes,
8860 .input_mux = &alc262_capture_source,
8861 .unsol_event = alc262_hippo_unsol_event,
8862 .init_hook = alc262_hippo_automute,
8864 [ALC262_HIPPO_1] = {
8865 .mixers = { alc262_hippo1_mixer },
8866 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
8867 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8868 .dac_nids = alc262_dac_nids,
8870 .dig_out_nid = ALC262_DIGOUT_NID,
8871 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8872 .channel_mode = alc262_modes,
8873 .input_mux = &alc262_capture_source,
8874 .unsol_event = alc262_hippo1_unsol_event,
8875 .init_hook = alc262_hippo1_automute,
8877 [ALC262_FUJITSU] = {
8878 .mixers = { alc262_fujitsu_mixer },
8879 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
8880 alc262_fujitsu_unsol_verbs },
8881 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8882 .dac_nids = alc262_dac_nids,
8884 .dig_out_nid = ALC262_DIGOUT_NID,
8885 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8886 .channel_mode = alc262_modes,
8887 .input_mux = &alc262_fujitsu_capture_source,
8888 .unsol_event = alc262_fujitsu_unsol_event,
8891 .mixers = { alc262_HP_BPC_mixer },
8892 .init_verbs = { alc262_HP_BPC_init_verbs },
8893 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8894 .dac_nids = alc262_dac_nids,
8896 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8897 .channel_mode = alc262_modes,
8898 .input_mux = &alc262_HP_capture_source,
8900 [ALC262_HP_BPC_D7000_WF] = {
8901 .mixers = { alc262_HP_BPC_WildWest_mixer },
8902 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8903 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8904 .dac_nids = alc262_dac_nids,
8906 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8907 .channel_mode = alc262_modes,
8908 .input_mux = &alc262_HP_D7000_capture_source,
8910 [ALC262_HP_BPC_D7000_WL] = {
8911 .mixers = { alc262_HP_BPC_WildWest_mixer,
8912 alc262_HP_BPC_WildWest_option_mixer },
8913 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8914 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8915 .dac_nids = alc262_dac_nids,
8917 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8918 .channel_mode = alc262_modes,
8919 .input_mux = &alc262_HP_D7000_capture_source,
8921 [ALC262_HP_TC_T5735] = {
8922 .mixers = { alc262_hp_t5735_mixer },
8923 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
8924 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8925 .dac_nids = alc262_dac_nids,
8927 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8928 .channel_mode = alc262_modes,
8929 .input_mux = &alc262_capture_source,
8930 .unsol_event = alc262_hp_t5735_unsol_event,
8931 .init_hook = alc262_hp_t5735_init_hook,
8933 [ALC262_BENQ_ED8] = {
8934 .mixers = { alc262_base_mixer },
8935 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8936 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8937 .dac_nids = alc262_dac_nids,
8939 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8940 .channel_mode = alc262_modes,
8941 .input_mux = &alc262_capture_source,
8943 [ALC262_SONY_ASSAMD] = {
8944 .mixers = { alc262_sony_mixer },
8945 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8946 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8947 .dac_nids = alc262_dac_nids,
8949 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8950 .channel_mode = alc262_modes,
8951 .input_mux = &alc262_capture_source,
8952 .unsol_event = alc262_hippo_unsol_event,
8953 .init_hook = alc262_hippo_automute,
8955 [ALC262_BENQ_T31] = {
8956 .mixers = { alc262_benq_t31_mixer },
8957 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8958 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8959 .dac_nids = alc262_dac_nids,
8961 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8962 .channel_mode = alc262_modes,
8963 .input_mux = &alc262_capture_source,
8964 .unsol_event = alc262_hippo_unsol_event,
8965 .init_hook = alc262_hippo_automute,
8968 .mixers = { alc262_ultra_mixer },
8969 .init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
8970 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8971 .dac_nids = alc262_dac_nids,
8973 .dig_out_nid = ALC262_DIGOUT_NID,
8974 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8975 .channel_mode = alc262_modes,
8976 .input_mux = &alc262_ultra_capture_source,
8977 .unsol_event = alc262_ultra_unsol_event,
8978 .init_hook = alc262_ultra_automute,
8982 static int patch_alc262(struct hda_codec *codec)
8984 struct alc_spec *spec;
8988 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8994 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
8999 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9000 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
9001 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9002 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
9006 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9010 if (board_config < 0) {
9011 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
9012 "trying auto-probe from BIOS...\n");
9013 board_config = ALC262_AUTO;
9016 if (board_config == ALC262_AUTO) {
9017 /* automatic parse from the BIOS config */
9018 err = alc262_parse_auto_config(codec);
9024 "hda_codec: Cannot set up configuration "
9025 "from BIOS. Using base mode...\n");
9026 board_config = ALC262_BASIC;
9030 if (board_config != ALC262_AUTO)
9031 setup_preset(spec, &alc262_presets[board_config]);
9033 spec->stream_name_analog = "ALC262 Analog";
9034 spec->stream_analog_playback = &alc262_pcm_analog_playback;
9035 spec->stream_analog_capture = &alc262_pcm_analog_capture;
9037 spec->stream_name_digital = "ALC262 Digital";
9038 spec->stream_digital_playback = &alc262_pcm_digital_playback;
9039 spec->stream_digital_capture = &alc262_pcm_digital_capture;
9041 if (!spec->adc_nids && spec->input_mux) {
9042 /* check whether NID 0x07 is valid */
9043 unsigned int wcap = get_wcaps(codec, 0x07);
9046 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9047 if (wcap != AC_WID_AUD_IN) {
9048 spec->adc_nids = alc262_adc_nids_alt;
9049 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
9050 spec->mixers[spec->num_mixers] =
9051 alc262_capture_alt_mixer;
9054 spec->adc_nids = alc262_adc_nids;
9055 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
9056 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
9061 codec->patch_ops = alc_patch_ops;
9062 if (board_config == ALC262_AUTO)
9063 spec->init_hook = alc262_auto_init;
9064 #ifdef CONFIG_SND_HDA_POWER_SAVE
9065 if (!spec->loopback.amplist)
9066 spec->loopback.amplist = alc262_loopbacks;
9073 * ALC268 channel source setting (2 channel)
9075 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
9076 #define alc268_modes alc260_modes
9078 static hda_nid_t alc268_dac_nids[2] = {
9083 static hda_nid_t alc268_adc_nids[2] = {
9088 static hda_nid_t alc268_adc_nids_alt[1] = {
9093 static struct snd_kcontrol_new alc268_base_mixer[] = {
9094 /* output mixer control */
9095 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9096 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9097 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9098 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9099 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9100 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9101 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9105 static struct hda_verb alc268_eapd_verbs[] = {
9106 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9107 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9111 /* Toshiba specific */
9112 #define alc268_toshiba_automute alc262_hippo_automute
9114 static struct hda_verb alc268_toshiba_verbs[] = {
9115 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9120 /* bind volumes of both NID 0x02 and 0x03 */
9121 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
9122 .ops = &snd_hda_bind_vol,
9124 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
9125 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
9130 /* mute/unmute internal speaker according to the hp jack and mute state */
9131 static void alc268_acer_automute(struct hda_codec *codec, int force)
9133 struct alc_spec *spec = codec->spec;
9136 if (force || !spec->sense_updated) {
9137 unsigned int present;
9138 present = snd_hda_codec_read(codec, 0x14, 0,
9139 AC_VERB_GET_PIN_SENSE, 0);
9140 spec->jack_present = (present & 0x80000000) != 0;
9141 spec->sense_updated = 1;
9143 if (spec->jack_present)
9144 mute = HDA_AMP_MUTE; /* mute internal speaker */
9145 else /* unmute internal speaker if necessary */
9146 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9147 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9148 HDA_AMP_MUTE, mute);
9152 /* bind hp and internal speaker mute (with plug check) */
9153 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
9154 struct snd_ctl_elem_value *ucontrol)
9156 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9157 long *valp = ucontrol->value.integer.value;
9160 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9162 valp[0] ? 0 : HDA_AMP_MUTE);
9163 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9165 valp[1] ? 0 : HDA_AMP_MUTE);
9167 alc268_acer_automute(codec, 0);
9171 static struct snd_kcontrol_new alc268_acer_mixer[] = {
9172 /* output mixer control */
9173 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9175 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9176 .name = "Master Playback Switch",
9177 .info = snd_hda_mixer_amp_switch_info,
9178 .get = snd_hda_mixer_amp_switch_get,
9179 .put = alc268_acer_master_sw_put,
9180 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9182 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9183 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9184 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9188 static struct hda_verb alc268_acer_verbs[] = {
9189 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9190 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9192 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9196 /* unsolicited event for HP jack sensing */
9197 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9200 if ((res >> 26) != ALC880_HP_EVENT)
9202 alc268_toshiba_automute(codec);
9205 static void alc268_acer_unsol_event(struct hda_codec *codec,
9208 if ((res >> 26) != ALC880_HP_EVENT)
9210 alc268_acer_automute(codec, 1);
9213 static void alc268_acer_init_hook(struct hda_codec *codec)
9215 alc268_acer_automute(codec, 1);
9219 * generic initialization of ADC, input mixers and output mixers
9221 static struct hda_verb alc268_base_init_verbs[] = {
9222 /* Unmute DAC0-1 and set vol = 0 */
9223 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9224 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9225 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9226 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9227 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9228 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9231 * Set up output mixers (0x0c - 0x0e)
9233 /* set vol=0 to output mixers */
9234 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9235 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9236 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9237 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
9239 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9240 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9242 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9243 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9244 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9245 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9246 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9247 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9248 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9249 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9251 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9252 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9253 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9254 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9255 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9256 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9257 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9258 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9260 /* Unmute Selector 23h,24h and set the default input to mic-in */
9262 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
9263 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9264 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
9265 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9271 * generic initialization of ADC, input mixers and output mixers
9273 static struct hda_verb alc268_volume_init_verbs[] = {
9274 /* set output DAC */
9275 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9276 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9277 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9278 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9280 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9281 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9282 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9283 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9284 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9286 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9287 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9288 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9289 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9290 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9292 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9293 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9294 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9295 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9297 /* set PCBEEP vol = 0 */
9298 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
9303 #define alc268_mux_enum_info alc_mux_enum_info
9304 #define alc268_mux_enum_get alc_mux_enum_get
9306 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
9307 struct snd_ctl_elem_value *ucontrol)
9309 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9310 struct alc_spec *spec = codec->spec;
9312 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9313 static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
9314 hda_nid_t nid = capture_mixers[adc_idx];
9316 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
9318 &spec->cur_mux[adc_idx]);
9321 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9322 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9323 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9325 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9326 /* The multiple "Capture Source" controls confuse alsamixer
9327 * So call somewhat different..
9328 * FIXME: the controls appear in the "playback" view!
9330 /* .name = "Capture Source", */
9331 .name = "Input Source",
9333 .info = alc268_mux_enum_info,
9334 .get = alc268_mux_enum_get,
9335 .put = alc268_mux_enum_put,
9340 static struct snd_kcontrol_new alc268_capture_mixer[] = {
9341 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9342 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9343 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9344 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9346 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9347 /* The multiple "Capture Source" controls confuse alsamixer
9348 * So call somewhat different..
9349 * FIXME: the controls appear in the "playback" view!
9351 /* .name = "Capture Source", */
9352 .name = "Input Source",
9354 .info = alc268_mux_enum_info,
9355 .get = alc268_mux_enum_get,
9356 .put = alc268_mux_enum_put,
9361 static struct hda_input_mux alc268_capture_source = {
9365 { "Front Mic", 0x1 },
9371 #ifdef CONFIG_SND_DEBUG
9372 static struct snd_kcontrol_new alc268_test_mixer[] = {
9373 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9374 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9375 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9376 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9378 /* Volume widgets */
9379 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9380 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9381 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9382 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
9383 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
9384 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
9385 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
9386 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
9387 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
9388 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
9389 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
9390 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
9391 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
9392 HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),
9393 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9394 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
9395 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
9396 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
9398 /* Modes for retasking pin widgets */
9399 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
9400 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
9401 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
9402 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
9404 /* Controls for GPIO pins, assuming they are configured as outputs */
9405 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
9406 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
9407 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
9408 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
9410 /* Switches to allow the digital SPDIF output pin to be enabled.
9411 * The ALC268 does not have an SPDIF input.
9413 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
9415 /* A switch allowing EAPD to be enabled. Some laptops seem to use
9416 * this output to turn on an external amplifier.
9418 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
9419 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
9425 /* create input playback/capture controls for the given pin */
9426 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9427 const char *ctlname, int idx)
9432 sprintf(name, "%s Playback Volume", ctlname);
9434 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9435 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9439 } else if (nid == 0x15) {
9440 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9441 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9447 sprintf(name, "%s Playback Switch", ctlname);
9448 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9449 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9455 /* add playback controls from the parsed DAC table */
9456 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9457 const struct auto_pin_cfg *cfg)
9462 spec->multiout.num_dacs = 2; /* only use one dac */
9463 spec->multiout.dac_nids = spec->private_dac_nids;
9464 spec->multiout.dac_nids[0] = 2;
9465 spec->multiout.dac_nids[1] = 3;
9467 nid = cfg->line_out_pins[0];
9469 alc268_new_analog_output(spec, nid, "Front", 0);
9471 nid = cfg->speaker_pins[0];
9473 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9474 "Speaker Playback Volume",
9475 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9479 nid = cfg->hp_pins[0];
9481 alc268_new_analog_output(spec, nid, "Headphone", 0);
9483 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
9485 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9486 "Mono Playback Switch",
9487 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
9494 /* create playback/capture controls for input pins */
9495 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
9496 const struct auto_pin_cfg *cfg)
9498 struct hda_input_mux *imux = &spec->private_imux;
9501 for (i = 0; i < AUTO_PIN_LAST; i++) {
9502 switch(cfg->input_pins[i]) {
9504 idx1 = 0; /* Mic 1 */
9507 idx1 = 1; /* Mic 2 */
9510 idx1 = 2; /* Line In */
9518 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9519 imux->items[imux->num_items].index = idx1;
9525 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
9527 struct alc_spec *spec = codec->spec;
9528 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9529 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9530 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9531 unsigned int dac_vol1, dac_vol2;
9534 snd_hda_codec_write(codec, speaker_nid, 0,
9535 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
9536 snd_hda_codec_write(codec, 0x0f, 0,
9537 AC_VERB_SET_AMP_GAIN_MUTE,
9539 snd_hda_codec_write(codec, 0x10, 0,
9540 AC_VERB_SET_AMP_GAIN_MUTE,
9543 snd_hda_codec_write(codec, 0x0f, 0,
9544 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9545 snd_hda_codec_write(codec, 0x10, 0,
9546 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9549 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
9550 if (line_nid == 0x14)
9551 dac_vol2 = AMP_OUT_ZERO;
9552 else if (line_nid == 0x15)
9553 dac_vol1 = AMP_OUT_ZERO;
9555 dac_vol2 = AMP_OUT_ZERO;
9556 else if (hp_nid == 0x15)
9557 dac_vol1 = AMP_OUT_ZERO;
9558 if (line_nid != 0x16 || hp_nid != 0x16 ||
9559 spec->autocfg.line_out_pins[1] != 0x16 ||
9560 spec->autocfg.line_out_pins[2] != 0x16)
9561 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
9563 snd_hda_codec_write(codec, 0x02, 0,
9564 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
9565 snd_hda_codec_write(codec, 0x03, 0,
9566 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
9569 /* pcm configuration: identiacal with ALC880 */
9570 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
9571 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
9572 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
9575 * BIOS auto configuration
9577 static int alc268_parse_auto_config(struct hda_codec *codec)
9579 struct alc_spec *spec = codec->spec;
9581 static hda_nid_t alc268_ignore[] = { 0 };
9583 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9587 if (!spec->autocfg.line_outs)
9588 return 0; /* can't find valid BIOS pin config */
9590 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
9593 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
9597 spec->multiout.max_channels = 2;
9599 /* digital only support output */
9600 if (spec->autocfg.dig_out_pin)
9601 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
9603 if (spec->kctl_alloc)
9604 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9606 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
9607 spec->num_mux_defs = 1;
9608 spec->input_mux = &spec->private_imux;
9610 err = alc_auto_add_mic_boost(codec);
9617 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
9618 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
9619 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
9621 /* init callback for auto-configuration model -- overriding the default init */
9622 static void alc268_auto_init(struct hda_codec *codec)
9624 alc268_auto_init_multi_out(codec);
9625 alc268_auto_init_hp_out(codec);
9626 alc268_auto_init_mono_speaker_out(codec);
9627 alc268_auto_init_analog_input(codec);
9631 * configuration and preset
9633 static const char *alc268_models[ALC268_MODEL_LAST] = {
9634 [ALC268_3ST] = "3stack",
9635 [ALC268_TOSHIBA] = "toshiba",
9636 [ALC268_ACER] = "acer",
9637 #ifdef CONFIG_SND_DEBUG
9638 [ALC268_TEST] = "test",
9640 [ALC268_AUTO] = "auto",
9643 static struct snd_pci_quirk alc268_cfg_tbl[] = {
9644 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
9645 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
9646 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
9647 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
9648 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
9649 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
9650 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
9654 static struct alc_config_preset alc268_presets[] = {
9656 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9657 .init_verbs = { alc268_base_init_verbs },
9658 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9659 .dac_nids = alc268_dac_nids,
9660 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9661 .adc_nids = alc268_adc_nids_alt,
9663 .dig_out_nid = ALC268_DIGOUT_NID,
9664 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9665 .channel_mode = alc268_modes,
9666 .input_mux = &alc268_capture_source,
9668 [ALC268_TOSHIBA] = {
9669 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9670 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9671 alc268_toshiba_verbs },
9672 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9673 .dac_nids = alc268_dac_nids,
9674 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9675 .adc_nids = alc268_adc_nids_alt,
9677 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9678 .channel_mode = alc268_modes,
9679 .input_mux = &alc268_capture_source,
9680 .unsol_event = alc268_toshiba_unsol_event,
9681 .init_hook = alc268_toshiba_automute,
9684 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
9685 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9686 alc268_acer_verbs },
9687 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9688 .dac_nids = alc268_dac_nids,
9689 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9690 .adc_nids = alc268_adc_nids_alt,
9692 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9693 .channel_mode = alc268_modes,
9694 .input_mux = &alc268_capture_source,
9695 .unsol_event = alc268_acer_unsol_event,
9696 .init_hook = alc268_acer_init_hook,
9698 #ifdef CONFIG_SND_DEBUG
9700 .mixers = { alc268_test_mixer, alc268_capture_mixer },
9701 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9702 alc268_volume_init_verbs },
9703 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9704 .dac_nids = alc268_dac_nids,
9705 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9706 .adc_nids = alc268_adc_nids_alt,
9708 .dig_out_nid = ALC268_DIGOUT_NID,
9709 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9710 .channel_mode = alc268_modes,
9711 .input_mux = &alc268_capture_source,
9716 static int patch_alc268(struct hda_codec *codec)
9718 struct alc_spec *spec;
9722 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
9728 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
9732 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9733 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
9734 "trying auto-probe from BIOS...\n");
9735 board_config = ALC268_AUTO;
9738 if (board_config == ALC268_AUTO) {
9739 /* automatic parse from the BIOS config */
9740 err = alc268_parse_auto_config(codec);
9746 "hda_codec: Cannot set up configuration "
9747 "from BIOS. Using base mode...\n");
9748 board_config = ALC268_3ST;
9752 if (board_config != ALC268_AUTO)
9753 setup_preset(spec, &alc268_presets[board_config]);
9755 spec->stream_name_analog = "ALC268 Analog";
9756 spec->stream_analog_playback = &alc268_pcm_analog_playback;
9757 spec->stream_analog_capture = &alc268_pcm_analog_capture;
9759 spec->stream_name_digital = "ALC268 Digital";
9760 spec->stream_digital_playback = &alc268_pcm_digital_playback;
9762 if (board_config == ALC268_AUTO) {
9763 if (!spec->adc_nids && spec->input_mux) {
9764 /* check whether NID 0x07 is valid */
9765 unsigned int wcap = get_wcaps(codec, 0x07);
9768 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9769 if (wcap != AC_WID_AUD_IN) {
9770 spec->adc_nids = alc268_adc_nids_alt;
9771 spec->num_adc_nids =
9772 ARRAY_SIZE(alc268_adc_nids_alt);
9773 spec->mixers[spec->num_mixers] =
9774 alc268_capture_alt_mixer;
9777 spec->adc_nids = alc268_adc_nids;
9778 spec->num_adc_nids =
9779 ARRAY_SIZE(alc268_adc_nids);
9780 spec->mixers[spec->num_mixers] =
9781 alc268_capture_mixer;
9786 codec->patch_ops = alc_patch_ops;
9787 if (board_config == ALC268_AUTO)
9788 spec->init_hook = alc268_auto_init;
9794 * ALC269 channel source setting (2 channel)
9796 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
9798 #define alc269_dac_nids alc260_dac_nids
9800 static hda_nid_t alc269_adc_nids[1] = {
9805 #define alc269_modes alc260_modes
9806 #define alc269_capture_source alc880_lg_lw_capture_source
9808 static struct snd_kcontrol_new alc269_base_mixer[] = {
9809 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9810 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9811 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9812 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9814 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9815 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9816 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9817 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9818 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9819 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9820 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9824 /* capture mixer elements */
9825 static struct snd_kcontrol_new alc269_capture_mixer[] = {
9826 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9827 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9829 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9830 /* The multiple "Capture Source" controls confuse alsamixer
9831 * So call somewhat different..
9832 * FIXME: the controls appear in the "playback" view!
9834 /* .name = "Capture Source", */
9835 .name = "Input Source",
9837 .info = alc_mux_enum_info,
9838 .get = alc_mux_enum_get,
9839 .put = alc_mux_enum_put,
9845 * generic initialization of ADC, input mixers and output mixers
9847 static struct hda_verb alc269_init_verbs[] = {
9849 * Unmute ADC0 and set the default input to mic-in
9851 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9853 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
9854 * analog-loopback mixer widget
9855 * Note: PASD motherboards uses the Line In 2 as the input for
9856 * front panel mic (mic 2)
9858 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9859 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9860 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9861 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9862 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9863 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9866 * Set up output mixers (0x0c - 0x0e)
9868 /* set vol=0 to output mixers */
9869 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9870 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9872 /* set up input amps for analog loopback */
9873 /* Amp Indices: DAC = 0, mixer = 1 */
9874 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9875 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9876 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9877 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9878 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9879 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9881 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9882 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9883 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9884 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9885 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9886 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9887 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9889 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9890 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9891 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9892 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9893 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9894 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9895 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9897 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9898 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9900 /* FIXME: use matrix-type input source selection */
9901 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
9902 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9903 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9904 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9905 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9906 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9909 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9910 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9914 /* add playback controls from the parsed DAC table */
9915 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
9916 const struct auto_pin_cfg *cfg)
9921 spec->multiout.num_dacs = 1; /* only use one dac */
9922 spec->multiout.dac_nids = spec->private_dac_nids;
9923 spec->multiout.dac_nids[0] = 2;
9925 nid = cfg->line_out_pins[0];
9927 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9928 "Front Playback Volume",
9929 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
9932 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9933 "Front Playback Switch",
9934 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9939 nid = cfg->speaker_pins[0];
9941 if (!cfg->line_out_pins[0]) {
9942 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9943 "Speaker Playback Volume",
9944 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
9950 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9951 "Speaker Playback Switch",
9952 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9957 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9958 "Speaker Playback Switch",
9959 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9965 nid = cfg->hp_pins[0];
9967 /* spec->multiout.hp_nid = 2; */
9968 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
9969 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9970 "Headphone Playback Volume",
9971 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
9977 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9978 "Headphone Playback Switch",
9979 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9984 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9985 "Headphone Playback Switch",
9986 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9995 #define alc269_auto_create_analog_input_ctls \
9996 alc880_auto_create_analog_input_ctls
9998 #ifdef CONFIG_SND_HDA_POWER_SAVE
9999 #define alc269_loopbacks alc880_loopbacks
10002 /* pcm configuration: identiacal with ALC880 */
10003 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
10004 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
10005 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
10006 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
10009 * BIOS auto configuration
10011 static int alc269_parse_auto_config(struct hda_codec *codec)
10013 struct alc_spec *spec = codec->spec;
10015 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
10017 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10022 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
10025 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
10029 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10031 if (spec->autocfg.dig_out_pin)
10032 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
10034 if (spec->kctl_alloc)
10035 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10037 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
10038 spec->num_mux_defs = 1;
10039 spec->input_mux = &spec->private_imux;
10041 err = alc_auto_add_mic_boost(codec);
10048 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
10049 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
10050 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
10053 /* init callback for auto-configuration model -- overriding the default init */
10054 static void alc269_auto_init(struct hda_codec *codec)
10056 alc269_auto_init_multi_out(codec);
10057 alc269_auto_init_hp_out(codec);
10058 alc269_auto_init_analog_input(codec);
10062 * configuration and preset
10064 static const char *alc269_models[ALC269_MODEL_LAST] = {
10065 [ALC269_BASIC] = "basic",
10068 static struct snd_pci_quirk alc269_cfg_tbl[] = {
10072 static struct alc_config_preset alc269_presets[] = {
10074 .mixers = { alc269_base_mixer },
10075 .init_verbs = { alc269_init_verbs },
10076 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
10077 .dac_nids = alc269_dac_nids,
10079 .num_channel_mode = ARRAY_SIZE(alc269_modes),
10080 .channel_mode = alc269_modes,
10081 .input_mux = &alc269_capture_source,
10085 static int patch_alc269(struct hda_codec *codec)
10087 struct alc_spec *spec;
10091 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10095 codec->spec = spec;
10097 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
10101 if (board_config < 0) {
10102 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
10103 "trying auto-probe from BIOS...\n");
10104 board_config = ALC269_AUTO;
10107 if (board_config == ALC269_AUTO) {
10108 /* automatic parse from the BIOS config */
10109 err = alc269_parse_auto_config(codec);
10115 "hda_codec: Cannot set up configuration "
10116 "from BIOS. Using base mode...\n");
10117 board_config = ALC269_BASIC;
10121 if (board_config != ALC269_AUTO)
10122 setup_preset(spec, &alc269_presets[board_config]);
10124 spec->stream_name_analog = "ALC269 Analog";
10125 spec->stream_analog_playback = &alc269_pcm_analog_playback;
10126 spec->stream_analog_capture = &alc269_pcm_analog_capture;
10128 spec->stream_name_digital = "ALC269 Digital";
10129 spec->stream_digital_playback = &alc269_pcm_digital_playback;
10130 spec->stream_digital_capture = &alc269_pcm_digital_capture;
10132 spec->adc_nids = alc269_adc_nids;
10133 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
10134 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
10135 spec->num_mixers++;
10137 codec->patch_ops = alc_patch_ops;
10138 if (board_config == ALC269_AUTO)
10139 spec->init_hook = alc269_auto_init;
10140 #ifdef CONFIG_SND_HDA_POWER_SAVE
10141 if (!spec->loopback.amplist)
10142 spec->loopback.amplist = alc269_loopbacks;
10149 * ALC861 channel source setting (2/6 channel selection for 3-stack)
10153 * set the path ways for 2 channel output
10154 * need to set the codec line out and mic 1 pin widgets to inputs
10156 static struct hda_verb alc861_threestack_ch2_init[] = {
10157 /* set pin widget 1Ah (line in) for input */
10158 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10159 /* set pin widget 18h (mic1/2) for input, for mic also enable
10162 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10164 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10166 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10167 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10173 * need to set the codec line out and mic 1 pin widgets to outputs
10175 static struct hda_verb alc861_threestack_ch6_init[] = {
10176 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10177 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10178 /* set pin widget 18h (mic1) for output (CLFE)*/
10179 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10181 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10182 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10184 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10186 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10187 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10192 static struct hda_channel_mode alc861_threestack_modes[2] = {
10193 { 2, alc861_threestack_ch2_init },
10194 { 6, alc861_threestack_ch6_init },
10196 /* Set mic1 as input and unmute the mixer */
10197 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
10198 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10199 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10202 /* Set mic1 as output and mute mixer */
10203 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
10204 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10205 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10209 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
10210 { 2, alc861_uniwill_m31_ch2_init },
10211 { 4, alc861_uniwill_m31_ch4_init },
10214 /* Set mic1 and line-in as input and unmute the mixer */
10215 static struct hda_verb alc861_asus_ch2_init[] = {
10216 /* set pin widget 1Ah (line in) for input */
10217 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10218 /* set pin widget 18h (mic1/2) for input, for mic also enable
10221 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10223 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10225 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10226 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10230 /* Set mic1 nad line-in as output and mute mixer */
10231 static struct hda_verb alc861_asus_ch6_init[] = {
10232 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10233 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10234 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10235 /* set pin widget 18h (mic1) for output (CLFE)*/
10236 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10237 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10238 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10239 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10241 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10243 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10244 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10249 static struct hda_channel_mode alc861_asus_modes[2] = {
10250 { 2, alc861_asus_ch2_init },
10251 { 6, alc861_asus_ch6_init },
10256 static struct snd_kcontrol_new alc861_base_mixer[] = {
10257 /* output mixer control */
10258 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10259 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10260 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10261 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10262 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10264 /*Input mixer control */
10265 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10266 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10267 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10268 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10269 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10270 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10271 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10272 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10273 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10274 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10276 /* Capture mixer control */
10277 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10278 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10280 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10281 .name = "Capture Source",
10283 .info = alc_mux_enum_info,
10284 .get = alc_mux_enum_get,
10285 .put = alc_mux_enum_put,
10290 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
10291 /* output mixer control */
10292 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10293 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10294 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10295 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10296 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10298 /* Input mixer control */
10299 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10300 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10301 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10302 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10303 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10304 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10305 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10306 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10307 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10308 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10310 /* Capture mixer control */
10311 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10312 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10314 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10315 .name = "Capture Source",
10317 .info = alc_mux_enum_info,
10318 .get = alc_mux_enum_get,
10319 .put = alc_mux_enum_put,
10322 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10323 .name = "Channel Mode",
10324 .info = alc_ch_mode_info,
10325 .get = alc_ch_mode_get,
10326 .put = alc_ch_mode_put,
10327 .private_value = ARRAY_SIZE(alc861_threestack_modes),
10332 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
10333 /* output mixer control */
10334 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10336 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10338 /*Capture mixer control */
10339 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10340 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10342 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10343 .name = "Capture Source",
10345 .info = alc_mux_enum_info,
10346 .get = alc_mux_enum_get,
10347 .put = alc_mux_enum_put,
10353 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
10354 /* output mixer control */
10355 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10356 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10357 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10358 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10359 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10361 /* Input mixer control */
10362 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10363 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
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("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10367 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10368 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10369 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10370 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10371 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10373 /* Capture mixer control */
10374 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10375 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10377 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10378 .name = "Capture Source",
10380 .info = alc_mux_enum_info,
10381 .get = alc_mux_enum_get,
10382 .put = alc_mux_enum_put,
10385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10386 .name = "Channel Mode",
10387 .info = alc_ch_mode_info,
10388 .get = alc_ch_mode_get,
10389 .put = alc_ch_mode_put,
10390 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
10395 static struct snd_kcontrol_new alc861_asus_mixer[] = {
10396 /* output mixer control */
10397 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10398 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10399 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10400 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10401 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10403 /* Input mixer control */
10404 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10405 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10406 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10407 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10408 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10409 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10410 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10411 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10412 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10413 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
10415 /* Capture mixer control */
10416 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10417 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10419 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10420 .name = "Capture Source",
10422 .info = alc_mux_enum_info,
10423 .get = alc_mux_enum_get,
10424 .put = alc_mux_enum_put,
10427 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10428 .name = "Channel Mode",
10429 .info = alc_ch_mode_info,
10430 .get = alc_ch_mode_get,
10431 .put = alc_ch_mode_put,
10432 .private_value = ARRAY_SIZE(alc861_asus_modes),
10437 /* additional mixer */
10438 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
10439 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10440 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10441 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
10442 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
10447 * generic initialization of ADC, input mixers and output mixers
10449 static struct hda_verb alc861_base_init_verbs[] = {
10451 * Unmute ADC0 and set the default input to mic-in
10453 /* port-A for surround (rear panel) */
10454 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10455 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
10456 /* port-B for mic-in (rear panel) with vref */
10457 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10458 /* port-C for line-in (rear panel) */
10459 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10460 /* port-D for Front */
10461 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10462 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10463 /* port-E for HP out (front panel) */
10464 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10465 /* route front PCM to HP */
10466 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10467 /* port-F for mic-in (front panel) with vref */
10468 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10469 /* port-G for CLFE (rear panel) */
10470 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10471 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10472 /* port-H for side (rear panel) */
10473 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10474 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
10476 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10477 /* route front mic to ADC1*/
10478 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10479 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10481 /* Unmute DAC0~3 & spdif out*/
10482 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10483 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10484 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10485 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10486 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10488 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10489 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10490 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10491 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10492 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10494 /* Unmute Stereo Mixer 15 */
10495 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10496 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10497 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10498 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10500 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10501 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10502 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10503 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10504 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10505 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10506 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10507 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10508 /* hp used DAC 3 (Front) */
10509 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10510 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10515 static struct hda_verb alc861_threestack_init_verbs[] = {
10517 * Unmute ADC0 and set the default input to mic-in
10519 /* port-A for surround (rear panel) */
10520 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10521 /* port-B for mic-in (rear panel) with vref */
10522 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10523 /* port-C for line-in (rear panel) */
10524 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10525 /* port-D for Front */
10526 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10527 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10528 /* port-E for HP out (front panel) */
10529 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10530 /* route front PCM to HP */
10531 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10532 /* port-F for mic-in (front panel) with vref */
10533 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10534 /* port-G for CLFE (rear panel) */
10535 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10536 /* port-H for side (rear panel) */
10537 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10539 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10540 /* route front mic to ADC1*/
10541 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10542 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10543 /* Unmute DAC0~3 & spdif out*/
10544 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10545 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10546 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10547 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10548 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10550 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10551 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10552 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10553 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10554 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10556 /* Unmute Stereo Mixer 15 */
10557 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10558 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10559 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10560 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10562 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10563 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10564 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10565 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10566 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10567 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10568 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10569 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10570 /* hp used DAC 3 (Front) */
10571 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10572 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10576 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
10578 * Unmute ADC0 and set the default input to mic-in
10580 /* port-A for surround (rear panel) */
10581 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10582 /* port-B for mic-in (rear panel) with vref */
10583 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10584 /* port-C for line-in (rear panel) */
10585 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10586 /* port-D for Front */
10587 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10588 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10589 /* port-E for HP out (front panel) */
10590 /* this has to be set to VREF80 */
10591 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10592 /* route front PCM to HP */
10593 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10594 /* port-F for mic-in (front panel) with vref */
10595 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10596 /* port-G for CLFE (rear panel) */
10597 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10598 /* port-H for side (rear panel) */
10599 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10601 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10602 /* route front mic to ADC1*/
10603 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10604 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10605 /* Unmute DAC0~3 & spdif out*/
10606 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10607 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10608 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10609 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10610 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10612 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10613 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10614 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10615 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10616 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10618 /* Unmute Stereo Mixer 15 */
10619 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10620 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10621 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10622 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10624 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10625 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10626 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10627 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10628 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10629 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10630 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10631 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10632 /* hp used DAC 3 (Front) */
10633 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10634 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10638 static struct hda_verb alc861_asus_init_verbs[] = {
10640 * Unmute ADC0 and set the default input to mic-in
10642 /* port-A for surround (rear panel)
10643 * according to codec#0 this is the HP jack
10645 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
10646 /* route front PCM to HP */
10647 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
10648 /* port-B for mic-in (rear panel) with vref */
10649 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10650 /* port-C for line-in (rear panel) */
10651 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10652 /* port-D for Front */
10653 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10654 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10655 /* port-E for HP out (front panel) */
10656 /* this has to be set to VREF80 */
10657 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10658 /* route front PCM to HP */
10659 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10660 /* port-F for mic-in (front panel) with vref */
10661 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10662 /* port-G for CLFE (rear panel) */
10663 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10664 /* port-H for side (rear panel) */
10665 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10667 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10668 /* route front mic to ADC1*/
10669 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10670 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10671 /* Unmute DAC0~3 & spdif out*/
10672 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10673 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10674 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10675 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10676 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10677 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10678 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10679 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10680 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10681 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10683 /* Unmute Stereo Mixer 15 */
10684 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10685 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10686 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10687 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10689 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10690 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10691 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10692 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10693 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10694 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10695 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10696 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10697 /* hp used DAC 3 (Front) */
10698 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10699 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10703 /* additional init verbs for ASUS laptops */
10704 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
10705 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
10706 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
10711 * generic initialization of ADC, input mixers and output mixers
10713 static struct hda_verb alc861_auto_init_verbs[] = {
10715 * Unmute ADC0 and set the default input to mic-in
10717 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
10718 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10720 /* Unmute DAC0~3 & spdif out*/
10721 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10722 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10723 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10724 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10725 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10727 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10728 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10729 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10730 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10731 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10733 /* Unmute Stereo Mixer 15 */
10734 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10735 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10736 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10737 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
10739 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10740 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10741 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10742 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10743 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10744 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10745 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10746 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10748 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10749 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10750 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10751 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10752 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10753 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10754 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10755 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10757 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
10762 static struct hda_verb alc861_toshiba_init_verbs[] = {
10763 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10768 /* toggle speaker-output according to the hp-jack state */
10769 static void alc861_toshiba_automute(struct hda_codec *codec)
10771 unsigned int present;
10773 present = snd_hda_codec_read(codec, 0x0f, 0,
10774 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10775 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
10776 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10777 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
10778 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
10781 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
10784 if ((res >> 26) == ALC880_HP_EVENT)
10785 alc861_toshiba_automute(codec);
10788 /* pcm configuration: identiacal with ALC880 */
10789 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
10790 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
10791 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
10792 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
10795 #define ALC861_DIGOUT_NID 0x07
10797 static struct hda_channel_mode alc861_8ch_modes[1] = {
10801 static hda_nid_t alc861_dac_nids[4] = {
10802 /* front, surround, clfe, side */
10803 0x03, 0x06, 0x05, 0x04
10806 static hda_nid_t alc660_dac_nids[3] = {
10807 /* front, clfe, surround */
10811 static hda_nid_t alc861_adc_nids[1] = {
10816 static struct hda_input_mux alc861_capture_source = {
10820 { "Front Mic", 0x3 },
10827 /* fill in the dac_nids table from the parsed pin configuration */
10828 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
10829 const struct auto_pin_cfg *cfg)
10834 spec->multiout.dac_nids = spec->private_dac_nids;
10835 for (i = 0; i < cfg->line_outs; i++) {
10836 nid = cfg->line_out_pins[i];
10838 if (i >= ARRAY_SIZE(alc861_dac_nids))
10840 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
10843 spec->multiout.num_dacs = cfg->line_outs;
10847 /* add playback controls from the parsed DAC table */
10848 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
10849 const struct auto_pin_cfg *cfg)
10852 static const char *chname[4] = {
10853 "Front", "Surround", NULL /*CLFE*/, "Side"
10858 for (i = 0; i < cfg->line_outs; i++) {
10859 nid = spec->multiout.dac_nids[i];
10864 err = add_control(spec, ALC_CTL_BIND_MUTE,
10865 "Center Playback Switch",
10866 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
10870 err = add_control(spec, ALC_CTL_BIND_MUTE,
10871 "LFE Playback Switch",
10872 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10877 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
10879 if (nid == alc861_dac_nids[idx])
10881 sprintf(name, "%s Playback Switch", chname[idx]);
10882 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10883 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10892 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
10900 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
10902 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10903 "Headphone Playback Switch",
10904 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10907 spec->multiout.hp_nid = nid;
10912 /* create playback/capture controls for input pins */
10913 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
10914 const struct auto_pin_cfg *cfg)
10916 struct hda_input_mux *imux = &spec->private_imux;
10917 int i, err, idx, idx1;
10919 for (i = 0; i < AUTO_PIN_LAST; i++) {
10920 switch (cfg->input_pins[i]) {
10923 idx = 2; /* Line In */
10927 idx = 2; /* Line In */
10931 idx = 1; /* Mic In */
10935 idx = 1; /* Mic In */
10945 err = new_analog_input(spec, cfg->input_pins[i],
10946 auto_pin_cfg_labels[i], idx, 0x15);
10950 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
10951 imux->items[imux->num_items].index = idx1;
10957 static struct snd_kcontrol_new alc861_capture_mixer[] = {
10958 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10959 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10962 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10963 /* The multiple "Capture Source" controls confuse alsamixer
10964 * So call somewhat different..
10965 *FIXME: the controls appear in the "playback" view!
10967 /* .name = "Capture Source", */
10968 .name = "Input Source",
10970 .info = alc_mux_enum_info,
10971 .get = alc_mux_enum_get,
10972 .put = alc_mux_enum_put,
10977 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
10979 int pin_type, int dac_idx)
10981 /* set as output */
10983 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10985 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
10990 static void alc861_auto_init_multi_out(struct hda_codec *codec)
10992 struct alc_spec *spec = codec->spec;
10995 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
10996 for (i = 0; i < spec->autocfg.line_outs; i++) {
10997 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10998 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11000 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
11001 spec->multiout.dac_nids[i]);
11005 static void alc861_auto_init_hp_out(struct hda_codec *codec)
11007 struct alc_spec *spec = codec->spec;
11010 pin = spec->autocfg.hp_pins[0];
11011 if (pin) /* connect to front */
11012 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
11013 spec->multiout.dac_nids[0]);
11016 static void alc861_auto_init_analog_input(struct hda_codec *codec)
11018 struct alc_spec *spec = codec->spec;
11021 for (i = 0; i < AUTO_PIN_LAST; i++) {
11022 hda_nid_t nid = spec->autocfg.input_pins[i];
11023 if (nid >= 0x0c && nid <= 0x11) {
11024 snd_hda_codec_write(codec, nid, 0,
11025 AC_VERB_SET_PIN_WIDGET_CONTROL,
11026 i <= AUTO_PIN_FRONT_MIC ?
11027 PIN_VREF80 : PIN_IN);
11032 /* parse the BIOS configuration and set up the alc_spec */
11033 /* return 1 if successful, 0 if the proper config is not found,
11034 * or a negative error code
11036 static int alc861_parse_auto_config(struct hda_codec *codec)
11038 struct alc_spec *spec = codec->spec;
11040 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
11042 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11046 if (!spec->autocfg.line_outs)
11047 return 0; /* can't find valid BIOS pin config */
11049 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
11052 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
11055 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
11058 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
11062 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11064 if (spec->autocfg.dig_out_pin)
11065 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
11067 if (spec->kctl_alloc)
11068 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11070 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
11072 spec->num_mux_defs = 1;
11073 spec->input_mux = &spec->private_imux;
11075 spec->adc_nids = alc861_adc_nids;
11076 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
11077 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
11078 spec->num_mixers++;
11083 /* additional initialization for auto-configuration model */
11084 static void alc861_auto_init(struct hda_codec *codec)
11086 alc861_auto_init_multi_out(codec);
11087 alc861_auto_init_hp_out(codec);
11088 alc861_auto_init_analog_input(codec);
11091 #ifdef CONFIG_SND_HDA_POWER_SAVE
11092 static struct hda_amp_list alc861_loopbacks[] = {
11093 { 0x15, HDA_INPUT, 0 },
11094 { 0x15, HDA_INPUT, 1 },
11095 { 0x15, HDA_INPUT, 2 },
11096 { 0x15, HDA_INPUT, 3 },
11103 * configuration and preset
11105 static const char *alc861_models[ALC861_MODEL_LAST] = {
11106 [ALC861_3ST] = "3stack",
11107 [ALC660_3ST] = "3stack-660",
11108 [ALC861_3ST_DIG] = "3stack-dig",
11109 [ALC861_6ST_DIG] = "6stack-dig",
11110 [ALC861_UNIWILL_M31] = "uniwill-m31",
11111 [ALC861_TOSHIBA] = "toshiba",
11112 [ALC861_ASUS] = "asus",
11113 [ALC861_ASUS_LAPTOP] = "asus-laptop",
11114 [ALC861_AUTO] = "auto",
11117 static struct snd_pci_quirk alc861_cfg_tbl[] = {
11118 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
11119 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11120 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11121 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
11122 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
11123 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
11124 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
11125 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
11126 * Any other models that need this preset?
11128 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
11129 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
11130 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
11131 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
11132 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
11133 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
11134 /* FIXME: the below seems conflict */
11135 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
11136 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
11137 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
11141 static struct alc_config_preset alc861_presets[] = {
11143 .mixers = { alc861_3ST_mixer },
11144 .init_verbs = { alc861_threestack_init_verbs },
11145 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11146 .dac_nids = alc861_dac_nids,
11147 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11148 .channel_mode = alc861_threestack_modes,
11150 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11151 .adc_nids = alc861_adc_nids,
11152 .input_mux = &alc861_capture_source,
11154 [ALC861_3ST_DIG] = {
11155 .mixers = { alc861_base_mixer },
11156 .init_verbs = { alc861_threestack_init_verbs },
11157 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11158 .dac_nids = alc861_dac_nids,
11159 .dig_out_nid = ALC861_DIGOUT_NID,
11160 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11161 .channel_mode = alc861_threestack_modes,
11163 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11164 .adc_nids = alc861_adc_nids,
11165 .input_mux = &alc861_capture_source,
11167 [ALC861_6ST_DIG] = {
11168 .mixers = { alc861_base_mixer },
11169 .init_verbs = { alc861_base_init_verbs },
11170 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11171 .dac_nids = alc861_dac_nids,
11172 .dig_out_nid = ALC861_DIGOUT_NID,
11173 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
11174 .channel_mode = alc861_8ch_modes,
11175 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11176 .adc_nids = alc861_adc_nids,
11177 .input_mux = &alc861_capture_source,
11180 .mixers = { alc861_3ST_mixer },
11181 .init_verbs = { alc861_threestack_init_verbs },
11182 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
11183 .dac_nids = alc660_dac_nids,
11184 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11185 .channel_mode = alc861_threestack_modes,
11187 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11188 .adc_nids = alc861_adc_nids,
11189 .input_mux = &alc861_capture_source,
11191 [ALC861_UNIWILL_M31] = {
11192 .mixers = { alc861_uniwill_m31_mixer },
11193 .init_verbs = { alc861_uniwill_m31_init_verbs },
11194 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11195 .dac_nids = alc861_dac_nids,
11196 .dig_out_nid = ALC861_DIGOUT_NID,
11197 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
11198 .channel_mode = alc861_uniwill_m31_modes,
11200 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11201 .adc_nids = alc861_adc_nids,
11202 .input_mux = &alc861_capture_source,
11204 [ALC861_TOSHIBA] = {
11205 .mixers = { alc861_toshiba_mixer },
11206 .init_verbs = { alc861_base_init_verbs,
11207 alc861_toshiba_init_verbs },
11208 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11209 .dac_nids = alc861_dac_nids,
11210 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11211 .channel_mode = alc883_3ST_2ch_modes,
11212 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11213 .adc_nids = alc861_adc_nids,
11214 .input_mux = &alc861_capture_source,
11215 .unsol_event = alc861_toshiba_unsol_event,
11216 .init_hook = alc861_toshiba_automute,
11219 .mixers = { alc861_asus_mixer },
11220 .init_verbs = { alc861_asus_init_verbs },
11221 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11222 .dac_nids = alc861_dac_nids,
11223 .dig_out_nid = ALC861_DIGOUT_NID,
11224 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
11225 .channel_mode = alc861_asus_modes,
11228 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11229 .adc_nids = alc861_adc_nids,
11230 .input_mux = &alc861_capture_source,
11232 [ALC861_ASUS_LAPTOP] = {
11233 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
11234 .init_verbs = { alc861_asus_init_verbs,
11235 alc861_asus_laptop_init_verbs },
11236 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11237 .dac_nids = alc861_dac_nids,
11238 .dig_out_nid = ALC861_DIGOUT_NID,
11239 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11240 .channel_mode = alc883_3ST_2ch_modes,
11242 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11243 .adc_nids = alc861_adc_nids,
11244 .input_mux = &alc861_capture_source,
11249 static int patch_alc861(struct hda_codec *codec)
11251 struct alc_spec *spec;
11255 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11259 codec->spec = spec;
11261 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
11265 if (board_config < 0) {
11266 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
11267 "trying auto-probe from BIOS...\n");
11268 board_config = ALC861_AUTO;
11271 if (board_config == ALC861_AUTO) {
11272 /* automatic parse from the BIOS config */
11273 err = alc861_parse_auto_config(codec);
11279 "hda_codec: Cannot set up configuration "
11280 "from BIOS. Using base mode...\n");
11281 board_config = ALC861_3ST_DIG;
11285 if (board_config != ALC861_AUTO)
11286 setup_preset(spec, &alc861_presets[board_config]);
11288 spec->stream_name_analog = "ALC861 Analog";
11289 spec->stream_analog_playback = &alc861_pcm_analog_playback;
11290 spec->stream_analog_capture = &alc861_pcm_analog_capture;
11292 spec->stream_name_digital = "ALC861 Digital";
11293 spec->stream_digital_playback = &alc861_pcm_digital_playback;
11294 spec->stream_digital_capture = &alc861_pcm_digital_capture;
11296 codec->patch_ops = alc_patch_ops;
11297 if (board_config == ALC861_AUTO)
11298 spec->init_hook = alc861_auto_init;
11299 #ifdef CONFIG_SND_HDA_POWER_SAVE
11300 if (!spec->loopback.amplist)
11301 spec->loopback.amplist = alc861_loopbacks;
11308 * ALC861-VD support
11312 * In addition, an independent DAC
11314 #define ALC861VD_DIGOUT_NID 0x06
11316 static hda_nid_t alc861vd_dac_nids[4] = {
11317 /* front, surr, clfe, side surr */
11318 0x02, 0x03, 0x04, 0x05
11321 /* dac_nids for ALC660vd are in a different order - according to
11322 * Realtek's driver.
11323 * This should probably tesult in a different mixer for 6stack models
11324 * of ALC660vd codecs, but for now there is only 3stack mixer
11325 * - and it is the same as in 861vd.
11326 * adc_nids in ALC660vd are (is) the same as in 861vd
11328 static hda_nid_t alc660vd_dac_nids[3] = {
11329 /* front, rear, clfe, rear_surr */
11333 static hda_nid_t alc861vd_adc_nids[1] = {
11339 /* FIXME: should be a matrix-type input source selection */
11340 static struct hda_input_mux alc861vd_capture_source = {
11344 { "Front Mic", 0x1 },
11350 static struct hda_input_mux alc861vd_dallas_capture_source = {
11353 { "Front Mic", 0x0 },
11354 { "ATAPI Mic", 0x1 },
11355 { "Line In", 0x5 },
11359 static struct hda_input_mux alc861vd_hp_capture_source = {
11362 { "Front Mic", 0x0 },
11363 { "ATAPI Mic", 0x1 },
11367 #define alc861vd_mux_enum_info alc_mux_enum_info
11368 #define alc861vd_mux_enum_get alc_mux_enum_get
11370 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
11371 struct snd_ctl_elem_value *ucontrol)
11373 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11374 struct alc_spec *spec = codec->spec;
11375 const struct hda_input_mux *imux = spec->input_mux;
11376 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
11377 static hda_nid_t capture_mixers[1] = { 0x22 };
11378 hda_nid_t nid = capture_mixers[adc_idx];
11379 unsigned int *cur_val = &spec->cur_mux[adc_idx];
11380 unsigned int i, idx;
11382 idx = ucontrol->value.enumerated.item[0];
11383 if (idx >= imux->num_items)
11384 idx = imux->num_items - 1;
11385 if (*cur_val == idx)
11387 for (i = 0; i < imux->num_items; i++) {
11388 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
11389 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
11390 imux->items[i].index,
11400 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
11407 static struct hda_verb alc861vd_6stack_ch6_init[] = {
11408 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11409 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11410 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11411 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11418 static struct hda_verb alc861vd_6stack_ch8_init[] = {
11419 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11420 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11421 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11422 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11426 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
11427 { 6, alc861vd_6stack_ch6_init },
11428 { 8, alc861vd_6stack_ch8_init },
11431 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
11433 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11434 .name = "Channel Mode",
11435 .info = alc_ch_mode_info,
11436 .get = alc_ch_mode_get,
11437 .put = alc_ch_mode_put,
11442 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
11443 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11444 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11447 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11448 /* The multiple "Capture Source" controls confuse alsamixer
11449 * So call somewhat different..
11450 *FIXME: the controls appear in the "playback" view!
11452 /* .name = "Capture Source", */
11453 .name = "Input Source",
11455 .info = alc861vd_mux_enum_info,
11456 .get = alc861vd_mux_enum_get,
11457 .put = alc861vd_mux_enum_put,
11462 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11463 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11465 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
11466 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11467 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11469 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11470 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
11472 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
11474 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
11476 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11477 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
11479 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
11480 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
11482 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11484 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11485 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11486 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11488 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11489 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11490 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11492 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11493 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11495 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11496 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11498 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11499 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11504 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
11505 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11506 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11508 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11510 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11511 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11512 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11514 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11515 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11516 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11518 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11519 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11521 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11522 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11524 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11525 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11530 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
11531 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11532 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
11533 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11535 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11537 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11538 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11539 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11541 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11542 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11543 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11545 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11546 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11551 /* Pin assignment: Front=0x14, HP = 0x15,
11552 * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
11554 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
11555 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11556 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11557 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11558 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11559 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11560 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11561 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11562 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11563 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
11564 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
11568 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
11569 * Front Mic=0x18, ATAPI Mic = 0x19,
11571 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
11572 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11573 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11574 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11575 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11576 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11577 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11578 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11579 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11585 * generic initialization of ADC, input mixers and output mixers
11587 static struct hda_verb alc861vd_volume_init_verbs[] = {
11589 * Unmute ADC0 and set the default input to mic-in
11591 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11592 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11594 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
11595 * the analog-loopback mixer widget
11597 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11598 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11599 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11600 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11601 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11604 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
11605 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11606 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11607 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11608 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11611 * Set up output mixers (0x02 - 0x05)
11613 /* set vol=0 to output mixers */
11614 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11615 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11616 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11617 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11619 /* set up input amps for analog loopback */
11620 /* Amp Indices: DAC = 0, mixer = 1 */
11621 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11622 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11623 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11624 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11625 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11626 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11627 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11628 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11634 * 3-stack pin configuration:
11635 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
11637 static struct hda_verb alc861vd_3stack_init_verbs[] = {
11639 * Set pin mode and muting
11641 /* set front pin widgets 0x14 for output */
11642 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11643 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11644 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11646 /* Mic (rear) pin: input vref at 80% */
11647 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11648 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11649 /* Front Mic pin: input vref at 80% */
11650 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11651 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11652 /* Line In pin: input */
11653 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11654 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11655 /* Line-2 In: Headphone output (output 0 - 0x0c) */
11656 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11657 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11658 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11659 /* CD pin widget for input */
11660 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11666 * 6-stack pin configuration:
11668 static struct hda_verb alc861vd_6stack_init_verbs[] = {
11670 * Set pin mode and muting
11672 /* set front pin widgets 0x14 for output */
11673 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11674 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11675 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11677 /* Rear Pin: output 1 (0x0d) */
11678 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11679 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11680 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11681 /* CLFE Pin: output 2 (0x0e) */
11682 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11683 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11684 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
11685 /* Side Pin: output 3 (0x0f) */
11686 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11687 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11688 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
11690 /* Mic (rear) pin: input vref at 80% */
11691 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11692 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11693 /* Front Mic pin: input vref at 80% */
11694 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11695 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11696 /* Line In pin: input */
11697 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11698 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11699 /* Line-2 In: Headphone output (output 0 - 0x0c) */
11700 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11701 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11702 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11703 /* CD pin widget for input */
11704 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11709 static struct hda_verb alc861vd_eapd_verbs[] = {
11710 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11714 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
11715 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11716 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11717 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11718 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11719 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11723 /* toggle speaker-output according to the hp-jack state */
11724 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
11726 unsigned int present;
11727 unsigned char bits;
11729 present = snd_hda_codec_read(codec, 0x1b, 0,
11730 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11731 bits = present ? HDA_AMP_MUTE : 0;
11732 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11733 HDA_AMP_MUTE, bits);
11736 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
11738 unsigned int present;
11739 unsigned char bits;
11741 present = snd_hda_codec_read(codec, 0x18, 0,
11742 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11743 bits = present ? HDA_AMP_MUTE : 0;
11744 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
11745 HDA_AMP_MUTE, bits);
11748 static void alc861vd_lenovo_automute(struct hda_codec *codec)
11750 alc861vd_lenovo_hp_automute(codec);
11751 alc861vd_lenovo_mic_automute(codec);
11754 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
11757 switch (res >> 26) {
11758 case ALC880_HP_EVENT:
11759 alc861vd_lenovo_hp_automute(codec);
11761 case ALC880_MIC_EVENT:
11762 alc861vd_lenovo_mic_automute(codec);
11767 static struct hda_verb alc861vd_dallas_verbs[] = {
11768 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11769 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11770 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11771 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11773 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11774 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11775 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11776 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11777 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11778 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11779 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11780 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11782 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11783 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11784 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11785 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11786 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11787 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11788 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11789 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11791 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11792 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11793 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11794 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11795 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11796 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11797 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11798 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11800 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11801 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11802 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11803 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11805 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11806 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11807 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11812 /* toggle speaker-output according to the hp-jack state */
11813 static void alc861vd_dallas_automute(struct hda_codec *codec)
11815 unsigned int present;
11817 present = snd_hda_codec_read(codec, 0x15, 0,
11818 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11819 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11820 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11823 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
11825 if ((res >> 26) == ALC880_HP_EVENT)
11826 alc861vd_dallas_automute(codec);
11829 #ifdef CONFIG_SND_HDA_POWER_SAVE
11830 #define alc861vd_loopbacks alc880_loopbacks
11833 /* pcm configuration: identiacal with ALC880 */
11834 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
11835 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
11836 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
11837 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
11840 * configuration and preset
11842 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
11843 [ALC660VD_3ST] = "3stack-660",
11844 [ALC660VD_3ST_DIG] = "3stack-660-digout",
11845 [ALC861VD_3ST] = "3stack",
11846 [ALC861VD_3ST_DIG] = "3stack-digout",
11847 [ALC861VD_6ST_DIG] = "6stack-digout",
11848 [ALC861VD_LENOVO] = "lenovo",
11849 [ALC861VD_DALLAS] = "dallas",
11850 [ALC861VD_HP] = "hp",
11851 [ALC861VD_AUTO] = "auto",
11854 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
11855 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
11856 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
11857 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
11858 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
11859 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
11860 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
11861 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
11862 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
11863 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
11864 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
11865 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
11866 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
11867 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
11868 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
11872 static struct alc_config_preset alc861vd_presets[] = {
11874 .mixers = { alc861vd_3st_mixer },
11875 .init_verbs = { alc861vd_volume_init_verbs,
11876 alc861vd_3stack_init_verbs },
11877 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11878 .dac_nids = alc660vd_dac_nids,
11879 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11880 .adc_nids = alc861vd_adc_nids,
11881 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11882 .channel_mode = alc861vd_3stack_2ch_modes,
11883 .input_mux = &alc861vd_capture_source,
11885 [ALC660VD_3ST_DIG] = {
11886 .mixers = { alc861vd_3st_mixer },
11887 .init_verbs = { alc861vd_volume_init_verbs,
11888 alc861vd_3stack_init_verbs },
11889 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11890 .dac_nids = alc660vd_dac_nids,
11891 .dig_out_nid = ALC861VD_DIGOUT_NID,
11892 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11893 .adc_nids = alc861vd_adc_nids,
11894 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11895 .channel_mode = alc861vd_3stack_2ch_modes,
11896 .input_mux = &alc861vd_capture_source,
11899 .mixers = { alc861vd_3st_mixer },
11900 .init_verbs = { alc861vd_volume_init_verbs,
11901 alc861vd_3stack_init_verbs },
11902 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11903 .dac_nids = alc861vd_dac_nids,
11904 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11905 .channel_mode = alc861vd_3stack_2ch_modes,
11906 .input_mux = &alc861vd_capture_source,
11908 [ALC861VD_3ST_DIG] = {
11909 .mixers = { alc861vd_3st_mixer },
11910 .init_verbs = { alc861vd_volume_init_verbs,
11911 alc861vd_3stack_init_verbs },
11912 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11913 .dac_nids = alc861vd_dac_nids,
11914 .dig_out_nid = ALC861VD_DIGOUT_NID,
11915 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11916 .channel_mode = alc861vd_3stack_2ch_modes,
11917 .input_mux = &alc861vd_capture_source,
11919 [ALC861VD_6ST_DIG] = {
11920 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
11921 .init_verbs = { alc861vd_volume_init_verbs,
11922 alc861vd_6stack_init_verbs },
11923 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11924 .dac_nids = alc861vd_dac_nids,
11925 .dig_out_nid = ALC861VD_DIGOUT_NID,
11926 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
11927 .channel_mode = alc861vd_6stack_modes,
11928 .input_mux = &alc861vd_capture_source,
11930 [ALC861VD_LENOVO] = {
11931 .mixers = { alc861vd_lenovo_mixer },
11932 .init_verbs = { alc861vd_volume_init_verbs,
11933 alc861vd_3stack_init_verbs,
11934 alc861vd_eapd_verbs,
11935 alc861vd_lenovo_unsol_verbs },
11936 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11937 .dac_nids = alc660vd_dac_nids,
11938 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11939 .adc_nids = alc861vd_adc_nids,
11940 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11941 .channel_mode = alc861vd_3stack_2ch_modes,
11942 .input_mux = &alc861vd_capture_source,
11943 .unsol_event = alc861vd_lenovo_unsol_event,
11944 .init_hook = alc861vd_lenovo_automute,
11946 [ALC861VD_DALLAS] = {
11947 .mixers = { alc861vd_dallas_mixer },
11948 .init_verbs = { alc861vd_dallas_verbs },
11949 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11950 .dac_nids = alc861vd_dac_nids,
11951 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11952 .adc_nids = alc861vd_adc_nids,
11953 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11954 .channel_mode = alc861vd_3stack_2ch_modes,
11955 .input_mux = &alc861vd_dallas_capture_source,
11956 .unsol_event = alc861vd_dallas_unsol_event,
11957 .init_hook = alc861vd_dallas_automute,
11960 .mixers = { alc861vd_hp_mixer },
11961 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
11962 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11963 .dac_nids = alc861vd_dac_nids,
11964 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11965 .dig_out_nid = ALC861VD_DIGOUT_NID,
11966 .adc_nids = alc861vd_adc_nids,
11967 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11968 .channel_mode = alc861vd_3stack_2ch_modes,
11969 .input_mux = &alc861vd_hp_capture_source,
11970 .unsol_event = alc861vd_dallas_unsol_event,
11971 .init_hook = alc861vd_dallas_automute,
11976 * BIOS auto configuration
11978 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
11979 hda_nid_t nid, int pin_type, int dac_idx)
11981 /* set as output */
11982 snd_hda_codec_write(codec, nid, 0,
11983 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11984 snd_hda_codec_write(codec, nid, 0,
11985 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11988 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
11990 struct alc_spec *spec = codec->spec;
11993 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
11994 for (i = 0; i <= HDA_SIDE; i++) {
11995 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11996 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11998 alc861vd_auto_set_output_and_unmute(codec, nid,
12004 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
12006 struct alc_spec *spec = codec->spec;
12009 pin = spec->autocfg.hp_pins[0];
12010 if (pin) /* connect to front and use dac 0 */
12011 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
12014 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
12015 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
12017 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
12019 struct alc_spec *spec = codec->spec;
12022 for (i = 0; i < AUTO_PIN_LAST; i++) {
12023 hda_nid_t nid = spec->autocfg.input_pins[i];
12024 if (alc861vd_is_input_pin(nid)) {
12025 snd_hda_codec_write(codec, nid, 0,
12026 AC_VERB_SET_PIN_WIDGET_CONTROL,
12027 i <= AUTO_PIN_FRONT_MIC ?
12028 PIN_VREF80 : PIN_IN);
12029 if (nid != ALC861VD_PIN_CD_NID)
12030 snd_hda_codec_write(codec, nid, 0,
12031 AC_VERB_SET_AMP_GAIN_MUTE,
12037 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
12038 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
12040 /* add playback controls from the parsed DAC table */
12041 /* Based on ALC880 version. But ALC861VD has separate,
12042 * different NIDs for mute/unmute switch and volume control */
12043 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
12044 const struct auto_pin_cfg *cfg)
12047 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
12048 hda_nid_t nid_v, nid_s;
12051 for (i = 0; i < cfg->line_outs; i++) {
12052 if (!spec->multiout.dac_nids[i])
12054 nid_v = alc861vd_idx_to_mixer_vol(
12056 spec->multiout.dac_nids[i]));
12057 nid_s = alc861vd_idx_to_mixer_switch(
12059 spec->multiout.dac_nids[i]));
12063 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12064 "Center Playback Volume",
12065 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
12069 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12070 "LFE Playback Volume",
12071 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
12075 err = add_control(spec, ALC_CTL_BIND_MUTE,
12076 "Center Playback Switch",
12077 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
12081 err = add_control(spec, ALC_CTL_BIND_MUTE,
12082 "LFE Playback Switch",
12083 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
12088 sprintf(name, "%s Playback Volume", chname[i]);
12089 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12090 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
12094 sprintf(name, "%s Playback Switch", chname[i]);
12095 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12096 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
12105 /* add playback controls for speaker and HP outputs */
12106 /* Based on ALC880 version. But ALC861VD has separate,
12107 * different NIDs for mute/unmute switch and volume control */
12108 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
12109 hda_nid_t pin, const char *pfx)
12111 hda_nid_t nid_v, nid_s;
12118 if (alc880_is_fixed_pin(pin)) {
12119 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12120 /* specify the DAC as the extra output */
12121 if (!spec->multiout.hp_nid)
12122 spec->multiout.hp_nid = nid_v;
12124 spec->multiout.extra_out_nid[0] = nid_v;
12125 /* control HP volume/switch on the output mixer amp */
12126 nid_v = alc861vd_idx_to_mixer_vol(
12127 alc880_fixed_pin_idx(pin));
12128 nid_s = alc861vd_idx_to_mixer_switch(
12129 alc880_fixed_pin_idx(pin));
12131 sprintf(name, "%s Playback Volume", pfx);
12132 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12133 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
12136 sprintf(name, "%s Playback Switch", pfx);
12137 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12138 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
12141 } else if (alc880_is_multi_pin(pin)) {
12142 /* set manual connection */
12143 /* we have only a switch on HP-out PIN */
12144 sprintf(name, "%s Playback Switch", pfx);
12145 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12146 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12153 /* parse the BIOS configuration and set up the alc_spec
12154 * return 1 if successful, 0 if the proper config is not found,
12155 * or a negative error code
12156 * Based on ALC880 version - had to change it to override
12157 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
12158 static int alc861vd_parse_auto_config(struct hda_codec *codec)
12160 struct alc_spec *spec = codec->spec;
12162 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
12164 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12168 if (!spec->autocfg.line_outs)
12169 return 0; /* can't find valid BIOS pin config */
12171 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12174 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
12177 err = alc861vd_auto_create_extra_out(spec,
12178 spec->autocfg.speaker_pins[0],
12182 err = alc861vd_auto_create_extra_out(spec,
12183 spec->autocfg.hp_pins[0],
12187 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
12191 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12193 if (spec->autocfg.dig_out_pin)
12194 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
12196 if (spec->kctl_alloc)
12197 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12199 spec->init_verbs[spec->num_init_verbs++]
12200 = alc861vd_volume_init_verbs;
12202 spec->num_mux_defs = 1;
12203 spec->input_mux = &spec->private_imux;
12205 err = alc_auto_add_mic_boost(codec);
12212 /* additional initialization for auto-configuration model */
12213 static void alc861vd_auto_init(struct hda_codec *codec)
12215 alc861vd_auto_init_multi_out(codec);
12216 alc861vd_auto_init_hp_out(codec);
12217 alc861vd_auto_init_analog_input(codec);
12220 static int patch_alc861vd(struct hda_codec *codec)
12222 struct alc_spec *spec;
12223 int err, board_config;
12225 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12229 codec->spec = spec;
12231 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
12235 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
12236 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
12237 "ALC861VD, trying auto-probe from BIOS...\n");
12238 board_config = ALC861VD_AUTO;
12241 if (board_config == ALC861VD_AUTO) {
12242 /* automatic parse from the BIOS config */
12243 err = alc861vd_parse_auto_config(codec);
12249 "hda_codec: Cannot set up configuration "
12250 "from BIOS. Using base mode...\n");
12251 board_config = ALC861VD_3ST;
12255 if (board_config != ALC861VD_AUTO)
12256 setup_preset(spec, &alc861vd_presets[board_config]);
12258 spec->stream_name_analog = "ALC861VD Analog";
12259 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
12260 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
12262 spec->stream_name_digital = "ALC861VD Digital";
12263 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
12264 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
12266 spec->adc_nids = alc861vd_adc_nids;
12267 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
12269 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
12270 spec->num_mixers++;
12272 codec->patch_ops = alc_patch_ops;
12274 if (board_config == ALC861VD_AUTO)
12275 spec->init_hook = alc861vd_auto_init;
12276 #ifdef CONFIG_SND_HDA_POWER_SAVE
12277 if (!spec->loopback.amplist)
12278 spec->loopback.amplist = alc861vd_loopbacks;
12287 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
12288 * configuration. Each pin widget can choose any input DACs and a mixer.
12289 * Each ADC is connected from a mixer of all inputs. This makes possible
12290 * 6-channel independent captures.
12292 * In addition, an independent DAC for the multi-playback (not used in this
12295 #define ALC662_DIGOUT_NID 0x06
12296 #define ALC662_DIGIN_NID 0x0a
12298 static hda_nid_t alc662_dac_nids[4] = {
12299 /* front, rear, clfe, rear_surr */
12303 static hda_nid_t alc662_adc_nids[1] = {
12308 /* FIXME: should be a matrix-type input source selection */
12310 static struct hda_input_mux alc662_capture_source = {
12314 { "Front Mic", 0x1 },
12320 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
12328 static struct hda_input_mux alc662_eeepc_capture_source = {
12336 #define alc662_mux_enum_info alc_mux_enum_info
12337 #define alc662_mux_enum_get alc_mux_enum_get
12339 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
12340 struct snd_ctl_elem_value *ucontrol)
12342 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12343 struct alc_spec *spec = codec->spec;
12344 const struct hda_input_mux *imux = spec->input_mux;
12345 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
12346 static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
12347 hda_nid_t nid = capture_mixers[adc_idx];
12348 unsigned int *cur_val = &spec->cur_mux[adc_idx];
12349 unsigned int i, idx;
12351 idx = ucontrol->value.enumerated.item[0];
12352 if (idx >= imux->num_items)
12353 idx = imux->num_items - 1;
12354 if (*cur_val == idx)
12356 for (i = 0; i < imux->num_items; i++) {
12357 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
12358 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
12359 imux->items[i].index,
12368 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
12375 static struct hda_verb alc662_3ST_ch2_init[] = {
12376 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
12377 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12378 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
12379 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12386 static struct hda_verb alc662_3ST_ch6_init[] = {
12387 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12388 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12389 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
12390 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12391 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12392 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
12396 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
12397 { 2, alc662_3ST_ch2_init },
12398 { 6, alc662_3ST_ch6_init },
12404 static struct hda_verb alc662_sixstack_ch6_init[] = {
12405 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12406 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12407 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12414 static struct hda_verb alc662_sixstack_ch8_init[] = {
12415 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12416 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12417 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12421 static struct hda_channel_mode alc662_5stack_modes[2] = {
12422 { 2, alc662_sixstack_ch6_init },
12423 { 6, alc662_sixstack_ch8_init },
12426 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12427 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12430 static struct snd_kcontrol_new alc662_base_mixer[] = {
12431 /* output mixer control */
12432 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12433 HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
12434 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12435 HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12436 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12437 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12438 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12439 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12440 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12442 /*Input mixer control */
12443 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
12444 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
12445 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
12446 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
12447 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
12448 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
12449 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
12450 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
12454 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
12455 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12456 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12457 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12458 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12459 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12460 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12461 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12462 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12463 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12464 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12465 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12466 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12467 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12471 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
12472 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12473 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12474 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12475 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12476 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12477 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12478 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12479 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12480 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12481 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12482 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12483 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12484 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12485 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12486 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12487 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12488 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12489 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12490 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12494 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
12495 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12496 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12497 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12498 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
12499 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12500 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12501 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12502 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12503 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12507 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
12508 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12510 HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12511 HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12513 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
12514 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12515 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12517 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
12518 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12519 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12523 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
12525 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12526 .name = "Channel Mode",
12527 .info = alc_ch_mode_info,
12528 .get = alc_ch_mode_get,
12529 .put = alc_ch_mode_put,
12534 static struct hda_verb alc662_init_verbs[] = {
12535 /* ADC: mute amp left and right */
12536 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12537 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12538 /* Front mixer: unmute input/output amp left and right (volume = 0) */
12540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12544 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12546 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12547 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12548 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12549 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12550 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12551 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12553 /* Front Pin: output 0 (0x0c) */
12554 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12555 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12557 /* Rear Pin: output 1 (0x0d) */
12558 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12559 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12561 /* CLFE Pin: output 2 (0x0e) */
12562 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12563 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12565 /* Mic (rear) pin: input vref at 80% */
12566 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12567 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12568 /* Front Mic pin: input vref at 80% */
12569 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12570 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12571 /* Line In pin: input */
12572 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12573 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12574 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12575 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12576 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12577 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12578 /* CD pin widget for input */
12579 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12581 /* FIXME: use matrix-type input source selection */
12582 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12584 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12585 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12589 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12590 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12591 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12592 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12596 static struct hda_verb alc662_sue_init_verbs[] = {
12597 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
12598 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
12602 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
12603 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12604 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12609 * generic initialization of ADC, input mixers and output mixers
12611 static struct hda_verb alc662_auto_init_verbs[] = {
12613 * Unmute ADC and set the default input to mic-in
12615 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12616 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12618 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12620 * Note: PASD motherboards uses the Line In 2 as the input for front
12621 * panel mic (mic 2)
12623 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12624 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12625 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12626 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12627 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12628 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12631 * Set up output mixers (0x0c - 0x0f)
12633 /* set vol=0 to output mixers */
12634 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12635 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12636 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12638 /* set up input amps for analog loopback */
12639 /* Amp Indices: DAC = 0, mixer = 1 */
12640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12641 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12642 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12643 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12644 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12645 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12648 /* FIXME: use matrix-type input source selection */
12649 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12651 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12652 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12656 /* capture mixer elements */
12657 static struct snd_kcontrol_new alc662_capture_mixer[] = {
12658 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12659 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12661 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12662 /* The multiple "Capture Source" controls confuse alsamixer
12663 * So call somewhat different..
12664 * FIXME: the controls appear in the "playback" view!
12666 /* .name = "Capture Source", */
12667 .name = "Input Source",
12669 .info = alc662_mux_enum_info,
12670 .get = alc662_mux_enum_get,
12671 .put = alc662_mux_enum_put,
12676 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
12678 unsigned int present;
12679 unsigned char bits;
12681 present = snd_hda_codec_read(codec, 0x14, 0,
12682 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12683 bits = present ? HDA_AMP_MUTE : 0;
12684 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12685 HDA_AMP_MUTE, bits);
12688 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
12690 unsigned int present;
12691 unsigned char bits;
12693 present = snd_hda_codec_read(codec, 0x1b, 0,
12694 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12695 bits = present ? HDA_AMP_MUTE : 0;
12696 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12697 HDA_AMP_MUTE, bits);
12698 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12699 HDA_AMP_MUTE, bits);
12702 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
12705 if ((res >> 26) == ALC880_HP_EVENT)
12706 alc662_lenovo_101e_all_automute(codec);
12707 if ((res >> 26) == ALC880_FRONT_EVENT)
12708 alc662_lenovo_101e_ispeaker_automute(codec);
12711 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
12713 unsigned int present;
12715 present = snd_hda_codec_read(codec, 0x18, 0,
12716 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12717 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12718 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12719 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12720 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12721 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12722 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12723 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12724 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12727 /* unsolicited event for HP jack sensing */
12728 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
12731 if ((res >> 26) == ALC880_HP_EVENT)
12732 alc262_hippo1_automute( codec );
12734 if ((res >> 26) == ALC880_MIC_EVENT)
12735 alc662_eeepc_mic_automute(codec);
12738 static void alc662_eeepc_inithook(struct hda_codec *codec)
12740 alc262_hippo1_automute( codec );
12741 alc662_eeepc_mic_automute(codec);
12744 #ifdef CONFIG_SND_HDA_POWER_SAVE
12745 #define alc662_loopbacks alc880_loopbacks
12749 /* pcm configuration: identiacal with ALC880 */
12750 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
12751 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
12752 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
12753 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
12756 * configuration and preset
12758 static const char *alc662_models[ALC662_MODEL_LAST] = {
12759 [ALC662_3ST_2ch_DIG] = "3stack-dig",
12760 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
12761 [ALC662_3ST_6ch] = "3stack-6ch",
12762 [ALC662_5ST_DIG] = "6stack-dig",
12763 [ALC662_LENOVO_101E] = "lenovo-101e",
12764 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
12765 [ALC662_AUTO] = "auto",
12768 static struct snd_pci_quirk alc662_cfg_tbl[] = {
12769 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
12770 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
12774 static struct alc_config_preset alc662_presets[] = {
12775 [ALC662_3ST_2ch_DIG] = {
12776 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
12777 .init_verbs = { alc662_init_verbs },
12778 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12779 .dac_nids = alc662_dac_nids,
12780 .dig_out_nid = ALC662_DIGOUT_NID,
12781 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12782 .adc_nids = alc662_adc_nids,
12783 .dig_in_nid = ALC662_DIGIN_NID,
12784 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12785 .channel_mode = alc662_3ST_2ch_modes,
12786 .input_mux = &alc662_capture_source,
12788 [ALC662_3ST_6ch_DIG] = {
12789 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12790 alc662_capture_mixer },
12791 .init_verbs = { alc662_init_verbs },
12792 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12793 .dac_nids = alc662_dac_nids,
12794 .dig_out_nid = ALC662_DIGOUT_NID,
12795 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12796 .adc_nids = alc662_adc_nids,
12797 .dig_in_nid = ALC662_DIGIN_NID,
12798 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12799 .channel_mode = alc662_3ST_6ch_modes,
12801 .input_mux = &alc662_capture_source,
12803 [ALC662_3ST_6ch] = {
12804 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12805 alc662_capture_mixer },
12806 .init_verbs = { alc662_init_verbs },
12807 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12808 .dac_nids = alc662_dac_nids,
12809 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12810 .adc_nids = alc662_adc_nids,
12811 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12812 .channel_mode = alc662_3ST_6ch_modes,
12814 .input_mux = &alc662_capture_source,
12816 [ALC662_5ST_DIG] = {
12817 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
12818 alc662_capture_mixer },
12819 .init_verbs = { alc662_init_verbs },
12820 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12821 .dac_nids = alc662_dac_nids,
12822 .dig_out_nid = ALC662_DIGOUT_NID,
12823 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12824 .adc_nids = alc662_adc_nids,
12825 .dig_in_nid = ALC662_DIGIN_NID,
12826 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
12827 .channel_mode = alc662_5stack_modes,
12828 .input_mux = &alc662_capture_source,
12830 [ALC662_LENOVO_101E] = {
12831 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
12832 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
12833 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12834 .dac_nids = alc662_dac_nids,
12835 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12836 .adc_nids = alc662_adc_nids,
12837 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12838 .channel_mode = alc662_3ST_2ch_modes,
12839 .input_mux = &alc662_lenovo_101e_capture_source,
12840 .unsol_event = alc662_lenovo_101e_unsol_event,
12841 .init_hook = alc662_lenovo_101e_all_automute,
12843 [ALC662_ASUS_EEEPC_P701] = {
12844 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
12845 .init_verbs = { alc662_init_verbs,
12846 alc662_eeepc_sue_init_verbs },
12847 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12848 .dac_nids = alc662_dac_nids,
12849 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12850 .adc_nids = alc662_adc_nids,
12851 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12852 .channel_mode = alc662_3ST_2ch_modes,
12853 .input_mux = &alc662_eeepc_capture_source,
12854 .unsol_event = alc662_eeepc_unsol_event,
12855 .init_hook = alc662_eeepc_inithook,
12862 * BIOS auto configuration
12865 /* add playback controls from the parsed DAC table */
12866 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
12867 const struct auto_pin_cfg *cfg)
12870 static const char *chname[4] = {
12871 "Front", "Surround", NULL /*CLFE*/, "Side"
12876 for (i = 0; i < cfg->line_outs; i++) {
12877 if (!spec->multiout.dac_nids[i])
12879 nid = alc880_idx_to_dac(i);
12882 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12883 "Center Playback Volume",
12884 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12888 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12889 "LFE Playback Volume",
12890 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12894 err = add_control(spec, ALC_CTL_BIND_MUTE,
12895 "Center Playback Switch",
12896 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
12900 err = add_control(spec, ALC_CTL_BIND_MUTE,
12901 "LFE Playback Switch",
12902 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
12907 sprintf(name, "%s Playback Volume", chname[i]);
12908 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12909 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12913 sprintf(name, "%s Playback Switch", chname[i]);
12914 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12915 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
12924 /* add playback controls for speaker and HP outputs */
12925 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
12935 if (alc880_is_fixed_pin(pin)) {
12936 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12937 /* printk("DAC nid=%x\n",nid); */
12938 /* specify the DAC as the extra output */
12939 if (!spec->multiout.hp_nid)
12940 spec->multiout.hp_nid = nid;
12942 spec->multiout.extra_out_nid[0] = nid;
12943 /* control HP volume/switch on the output mixer amp */
12944 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12945 sprintf(name, "%s Playback Volume", pfx);
12946 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12947 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12950 sprintf(name, "%s Playback Switch", pfx);
12951 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12952 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
12955 } else if (alc880_is_multi_pin(pin)) {
12956 /* set manual connection */
12957 /* we have only a switch on HP-out PIN */
12958 sprintf(name, "%s Playback Switch", pfx);
12959 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12960 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12967 /* create playback/capture controls for input pins */
12968 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
12969 const struct auto_pin_cfg *cfg)
12971 struct hda_input_mux *imux = &spec->private_imux;
12974 for (i = 0; i < AUTO_PIN_LAST; i++) {
12975 if (alc880_is_input_pin(cfg->input_pins[i])) {
12976 idx = alc880_input_pin_idx(cfg->input_pins[i]);
12977 err = new_analog_input(spec, cfg->input_pins[i],
12978 auto_pin_cfg_labels[i],
12982 imux->items[imux->num_items].label =
12983 auto_pin_cfg_labels[i];
12984 imux->items[imux->num_items].index =
12985 alc880_input_pin_idx(cfg->input_pins[i]);
12992 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
12993 hda_nid_t nid, int pin_type,
12996 /* set as output */
12997 snd_hda_codec_write(codec, nid, 0,
12998 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
12999 snd_hda_codec_write(codec, nid, 0,
13000 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
13001 /* need the manual connection? */
13002 if (alc880_is_multi_pin(nid)) {
13003 struct alc_spec *spec = codec->spec;
13004 int idx = alc880_multi_pin_idx(nid);
13005 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
13006 AC_VERB_SET_CONNECT_SEL,
13007 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
13011 static void alc662_auto_init_multi_out(struct hda_codec *codec)
13013 struct alc_spec *spec = codec->spec;
13016 for (i = 0; i <= HDA_SIDE; i++) {
13017 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13018 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13020 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
13025 static void alc662_auto_init_hp_out(struct hda_codec *codec)
13027 struct alc_spec *spec = codec->spec;
13030 pin = spec->autocfg.hp_pins[0];
13031 if (pin) /* connect to front */
13033 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
13036 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
13037 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
13039 static void alc662_auto_init_analog_input(struct hda_codec *codec)
13041 struct alc_spec *spec = codec->spec;
13044 for (i = 0; i < AUTO_PIN_LAST; i++) {
13045 hda_nid_t nid = spec->autocfg.input_pins[i];
13046 if (alc662_is_input_pin(nid)) {
13047 snd_hda_codec_write(codec, nid, 0,
13048 AC_VERB_SET_PIN_WIDGET_CONTROL,
13049 (i <= AUTO_PIN_FRONT_MIC ?
13050 PIN_VREF80 : PIN_IN));
13051 if (nid != ALC662_PIN_CD_NID)
13052 snd_hda_codec_write(codec, nid, 0,
13053 AC_VERB_SET_AMP_GAIN_MUTE,
13059 static int alc662_parse_auto_config(struct hda_codec *codec)
13061 struct alc_spec *spec = codec->spec;
13063 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
13065 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13069 if (!spec->autocfg.line_outs)
13070 return 0; /* can't find valid BIOS pin config */
13072 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13075 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
13078 err = alc662_auto_create_extra_out(spec,
13079 spec->autocfg.speaker_pins[0],
13083 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
13087 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
13091 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13093 if (spec->autocfg.dig_out_pin)
13094 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
13096 if (spec->kctl_alloc)
13097 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13099 spec->num_mux_defs = 1;
13100 spec->input_mux = &spec->private_imux;
13102 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
13103 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
13104 spec->num_mixers++;
13108 /* additional initialization for auto-configuration model */
13109 static void alc662_auto_init(struct hda_codec *codec)
13111 alc662_auto_init_multi_out(codec);
13112 alc662_auto_init_hp_out(codec);
13113 alc662_auto_init_analog_input(codec);
13116 static int patch_alc662(struct hda_codec *codec)
13118 struct alc_spec *spec;
13119 int err, board_config;
13121 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13125 codec->spec = spec;
13127 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
13130 if (board_config < 0) {
13131 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
13132 "trying auto-probe from BIOS...\n");
13133 board_config = ALC662_AUTO;
13136 if (board_config == ALC662_AUTO) {
13137 /* automatic parse from the BIOS config */
13138 err = alc662_parse_auto_config(codec);
13144 "hda_codec: Cannot set up configuration "
13145 "from BIOS. Using base mode...\n");
13146 board_config = ALC662_3ST_2ch_DIG;
13150 if (board_config != ALC662_AUTO)
13151 setup_preset(spec, &alc662_presets[board_config]);
13153 spec->stream_name_analog = "ALC662 Analog";
13154 spec->stream_analog_playback = &alc662_pcm_analog_playback;
13155 spec->stream_analog_capture = &alc662_pcm_analog_capture;
13157 spec->stream_name_digital = "ALC662 Digital";
13158 spec->stream_digital_playback = &alc662_pcm_digital_playback;
13159 spec->stream_digital_capture = &alc662_pcm_digital_capture;
13161 if (!spec->adc_nids && spec->input_mux) {
13162 spec->adc_nids = alc662_adc_nids;
13163 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
13166 codec->patch_ops = alc_patch_ops;
13167 if (board_config == ALC662_AUTO)
13168 spec->init_hook = alc662_auto_init;
13169 #ifdef CONFIG_SND_HDA_POWER_SAVE
13170 if (!spec->loopback.amplist)
13171 spec->loopback.amplist = alc662_loopbacks;
13180 struct hda_codec_preset snd_hda_preset_realtek[] = {
13181 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
13182 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
13183 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
13184 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
13185 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
13186 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
13187 .patch = patch_alc861 },
13188 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
13189 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
13190 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
13191 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
13192 .patch = patch_alc883 },
13193 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
13194 .patch = patch_alc662 },
13195 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
13196 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
13197 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
13198 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
13199 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
13200 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
13201 {} /* terminator */