aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/hda_codec.c81
-rw-r--r--sound/pci/hda/hda_codec.h5
-rw-r--r--sound/pci/hda/hda_generic.c3
-rw-r--r--sound/pci/hda/hda_hwdep.c60
-rw-r--r--sound/pci/hda/hda_intel.c60
-rw-r--r--sound/pci/hda/hda_local.h14
-rw-r--r--sound/pci/hda/hda_proc.c31
-rw-r--r--sound/pci/hda/patch_analog.c117
-rw-r--r--sound/pci/hda/patch_cirrus.c14
-rw-r--r--sound/pci/hda/patch_cmedia.c11
-rw-r--r--sound/pci/hda/patch_conexant.c592
-rw-r--r--sound/pci/hda/patch_realtek.c1006
-rw-r--r--sound/pci/hda/patch_si3054.c1
-rw-r--r--sound/pci/hda/patch_sigmatel.c271
-rw-r--r--sound/pci/hda/patch_via.c274
15 files changed, 1810 insertions, 730 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index f98b47cd6cfb..76d3c4c049db 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -824,6 +824,9 @@ int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
824 struct hda_pincfg *pin; 824 struct hda_pincfg *pin;
825 unsigned int oldcfg; 825 unsigned int oldcfg;
826 826
827 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
828 return -EINVAL;
829
827 oldcfg = snd_hda_codec_get_pincfg(codec, nid); 830 oldcfg = snd_hda_codec_get_pincfg(codec, nid);
828 pin = look_up_pincfg(codec, list, nid); 831 pin = look_up_pincfg(codec, list, nid);
829 if (!pin) { 832 if (!pin) {
@@ -899,6 +902,25 @@ static void restore_pincfgs(struct hda_codec *codec)
899 } 902 }
900} 903}
901 904
905/**
906 * snd_hda_shutup_pins - Shut up all pins
907 * @codec: the HDA codec
908 *
909 * Clear all pin controls to shup up before suspend for avoiding click noise.
910 * The controls aren't cached so that they can be resumed properly.
911 */
912void snd_hda_shutup_pins(struct hda_codec *codec)
913{
914 int i;
915 for (i = 0; i < codec->init_pins.used; i++) {
916 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
917 /* use read here for syncing after issuing each verb */
918 snd_hda_codec_read(codec, pin->nid, 0,
919 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
920 }
921}
922EXPORT_SYMBOL_HDA(snd_hda_shutup_pins);
923
902static void init_hda_cache(struct hda_cache_rec *cache, 924static void init_hda_cache(struct hda_cache_rec *cache,
903 unsigned int record_size); 925 unsigned int record_size);
904static void free_hda_cache(struct hda_cache_rec *cache); 926static void free_hda_cache(struct hda_cache_rec *cache);
@@ -931,6 +953,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
931#endif 953#endif
932 list_del(&codec->list); 954 list_del(&codec->list);
933 snd_array_free(&codec->mixers); 955 snd_array_free(&codec->mixers);
956 snd_array_free(&codec->nids);
934 codec->bus->caddr_tbl[codec->addr] = NULL; 957 codec->bus->caddr_tbl[codec->addr] = NULL;
935 if (codec->patch_ops.free) 958 if (codec->patch_ops.free)
936 codec->patch_ops.free(codec); 959 codec->patch_ops.free(codec);
@@ -985,7 +1008,8 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr
985 mutex_init(&codec->control_mutex); 1008 mutex_init(&codec->control_mutex);
986 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); 1009 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
987 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); 1010 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
988 snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 60); 1011 snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
1012 snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
989 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); 1013 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
990 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); 1014 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
991 if (codec->bus->modelname) { 1015 if (codec->bus->modelname) {
@@ -1708,7 +1732,7 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1708EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); 1732EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
1709 1733
1710/** 1734/**
1711 * snd_hda_ctl-add - Add a control element and assign to the codec 1735 * snd_hda_ctl_add - Add a control element and assign to the codec
1712 * @codec: HD-audio codec 1736 * @codec: HD-audio codec
1713 * @nid: corresponding NID (optional) 1737 * @nid: corresponding NID (optional)
1714 * @kctl: the control element to assign 1738 * @kctl: the control element to assign
@@ -1723,19 +1747,25 @@ EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
1723 * 1747 *
1724 * snd_hda_ctl_add() checks the control subdev id field whether 1748 * snd_hda_ctl_add() checks the control subdev id field whether
1725 * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower 1749 * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower
1726 * bits value is taken as the NID to assign. 1750 * bits value is taken as the NID to assign. The #HDA_NID_ITEM_AMP bit
1751 * specifies if kctl->private_value is a HDA amplifier value.
1727 */ 1752 */
1728int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, 1753int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
1729 struct snd_kcontrol *kctl) 1754 struct snd_kcontrol *kctl)
1730{ 1755{
1731 int err; 1756 int err;
1757 unsigned short flags = 0;
1732 struct hda_nid_item *item; 1758 struct hda_nid_item *item;
1733 1759
1734 if (kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) { 1760 if (kctl->id.subdevice & HDA_SUBDEV_AMP_FLAG) {
1761 flags |= HDA_NID_ITEM_AMP;
1735 if (nid == 0) 1762 if (nid == 0)
1736 nid = kctl->id.subdevice & 0xffff; 1763 nid = get_amp_nid_(kctl->private_value);
1737 kctl->id.subdevice = 0;
1738 } 1764 }
1765 if ((kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) != 0 && nid == 0)
1766 nid = kctl->id.subdevice & 0xffff;
1767 if (kctl->id.subdevice & (HDA_SUBDEV_NID_FLAG|HDA_SUBDEV_AMP_FLAG))
1768 kctl->id.subdevice = 0;
1739 err = snd_ctl_add(codec->bus->card, kctl); 1769 err = snd_ctl_add(codec->bus->card, kctl);
1740 if (err < 0) 1770 if (err < 0)
1741 return err; 1771 return err;
@@ -1744,11 +1774,41 @@ int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
1744 return -ENOMEM; 1774 return -ENOMEM;
1745 item->kctl = kctl; 1775 item->kctl = kctl;
1746 item->nid = nid; 1776 item->nid = nid;
1777 item->flags = flags;
1747 return 0; 1778 return 0;
1748} 1779}
1749EXPORT_SYMBOL_HDA(snd_hda_ctl_add); 1780EXPORT_SYMBOL_HDA(snd_hda_ctl_add);
1750 1781
1751/** 1782/**
1783 * snd_hda_add_nid - Assign a NID to a control element
1784 * @codec: HD-audio codec
1785 * @nid: corresponding NID (optional)
1786 * @kctl: the control element to assign
1787 * @index: index to kctl
1788 *
1789 * Add the given control element to an array inside the codec instance.
1790 * This function is used when #snd_hda_ctl_add cannot be used for 1:1
1791 * NID:KCTL mapping - for example "Capture Source" selector.
1792 */
1793int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
1794 unsigned int index, hda_nid_t nid)
1795{
1796 struct hda_nid_item *item;
1797
1798 if (nid > 0) {
1799 item = snd_array_new(&codec->nids);
1800 if (!item)
1801 return -ENOMEM;
1802 item->kctl = kctl;
1803 item->index = index;
1804 item->nid = nid;
1805 return 0;
1806 }
1807 return -EINVAL;
1808}
1809EXPORT_SYMBOL_HDA(snd_hda_add_nid);
1810
1811/**
1752 * snd_hda_ctls_clear - Clear all controls assigned to the given codec 1812 * snd_hda_ctls_clear - Clear all controls assigned to the given codec
1753 * @codec: HD-audio codec 1813 * @codec: HD-audio codec
1754 */ 1814 */
@@ -1759,6 +1819,7 @@ void snd_hda_ctls_clear(struct hda_codec *codec)
1759 for (i = 0; i < codec->mixers.used; i++) 1819 for (i = 0; i < codec->mixers.used; i++)
1760 snd_ctl_remove(codec->bus->card, items[i].kctl); 1820 snd_ctl_remove(codec->bus->card, items[i].kctl);
1761 snd_array_free(&codec->mixers); 1821 snd_array_free(&codec->mixers);
1822 snd_array_free(&codec->nids);
1762} 1823}
1763 1824
1764/* pseudo device locking 1825/* pseudo device locking
@@ -2706,7 +2767,8 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2706 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, 2767 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
2707 power_state); 2768 power_state);
2708 /* partial workaround for "azx_get_response timeout" */ 2769 /* partial workaround for "azx_get_response timeout" */
2709 if (power_state == AC_PWRST_D0) 2770 if (power_state == AC_PWRST_D0 &&
2771 (codec->vendor_id & 0xffff0000) == 0x14f10000)
2710 msleep(10); 2772 msleep(10);
2711 2773
2712 nid = codec->start_nid; 2774 nid = codec->start_nid;
@@ -2740,7 +2802,6 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2740 if (power_state == AC_PWRST_D0) { 2802 if (power_state == AC_PWRST_D0) {
2741 unsigned long end_time; 2803 unsigned long end_time;
2742 int state; 2804 int state;
2743 msleep(10);
2744 /* wait until the codec reachs to D0 */ 2805 /* wait until the codec reachs to D0 */
2745 end_time = jiffies + msecs_to_jiffies(500); 2806 end_time = jiffies + msecs_to_jiffies(500);
2746 do { 2807 do {
@@ -3214,6 +3275,8 @@ const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = {
3214 3275
3215/* 3276/*
3216 * get the empty PCM device number to assign 3277 * get the empty PCM device number to assign
3278 *
3279 * note the max device number is limited by HDA_MAX_PCMS, currently 10
3217 */ 3280 */
3218static int get_empty_pcm_device(struct hda_bus *bus, int type) 3281static int get_empty_pcm_device(struct hda_bus *bus, int type)
3219{ 3282{
@@ -3478,6 +3541,8 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
3478 3541
3479 for (; knew->name; knew++) { 3542 for (; knew->name; knew++) {
3480 struct snd_kcontrol *kctl; 3543 struct snd_kcontrol *kctl;
3544 if (knew->iface == -1) /* skip this codec private value */
3545 continue;
3481 kctl = snd_ctl_new1(knew, codec); 3546 kctl = snd_ctl_new1(knew, codec);
3482 if (!kctl) 3547 if (!kctl)
3483 return -ENOMEM; 3548 return -ENOMEM;
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 0a770a28e71f..b75da47571e6 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -527,6 +527,9 @@ enum {
527/* max. codec address */ 527/* max. codec address */
528#define HDA_MAX_CODEC_ADDRESS 0x0f 528#define HDA_MAX_CODEC_ADDRESS 0x0f
529 529
530/* max number of PCM devics per card */
531#define HDA_MAX_PCMS 10
532
530/* 533/*
531 * generic arrays 534 * generic arrays
532 */ 535 */
@@ -789,6 +792,7 @@ struct hda_codec {
789 u32 *wcaps; 792 u32 *wcaps;
790 793
791 struct snd_array mixers; /* list of assigned mixer elements */ 794 struct snd_array mixers; /* list of assigned mixer elements */
795 struct snd_array nids; /* list of mapped mixer elements */
792 796
793 struct hda_cache_rec amp_cache; /* cache for amp access */ 797 struct hda_cache_rec amp_cache; /* cache for amp access */
794 struct hda_cache_rec cmd_cache; /* cache for other commands */ 798 struct hda_cache_rec cmd_cache; /* cache for other commands */
@@ -898,6 +902,7 @@ int snd_hda_codec_set_pincfg(struct hda_codec *codec, hda_nid_t nid,
898 unsigned int cfg); 902 unsigned int cfg);
899int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list, 903int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
900 hda_nid_t nid, unsigned int cfg); /* for hwdep */ 904 hda_nid_t nid, unsigned int cfg); /* for hwdep */
905void snd_hda_shutup_pins(struct hda_codec *codec);
901 906
902/* 907/*
903 * Mixer 908 * Mixer
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 092c6a7c2ff3..5ea21285ee1f 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -861,7 +861,8 @@ static int build_input_controls(struct hda_codec *codec)
861 } 861 }
862 862
863 /* create input MUX if multiple sources are available */ 863 /* create input MUX if multiple sources are available */
864 err = snd_hda_ctl_add(codec, 0, snd_ctl_new1(&cap_sel, codec)); 864 err = snd_hda_ctl_add(codec, spec->adc_node->nid,
865 snd_ctl_new1(&cap_sel, codec));
865 if (err < 0) 866 if (err < 0)
866 return err; 867 return err;
867 868
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 40ccb419b6e9..a1fc83753cc6 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -293,8 +293,11 @@ static ssize_t type##_store(struct device *dev, \
293{ \ 293{ \
294 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ 294 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
295 struct hda_codec *codec = hwdep->private_data; \ 295 struct hda_codec *codec = hwdep->private_data; \
296 char *after; \ 296 unsigned long val; \
297 codec->type = simple_strtoul(buf, &after, 0); \ 297 int err = strict_strtoul(buf, 0, &val); \
298 if (err < 0) \
299 return err; \
300 codec->type = val; \
298 return count; \ 301 return count; \
299} 302}
300 303
@@ -622,6 +625,10 @@ enum {
622 LINE_MODE_PINCFG, 625 LINE_MODE_PINCFG,
623 LINE_MODE_VERB, 626 LINE_MODE_VERB,
624 LINE_MODE_HINT, 627 LINE_MODE_HINT,
628 LINE_MODE_VENDOR_ID,
629 LINE_MODE_SUBSYSTEM_ID,
630 LINE_MODE_REVISION_ID,
631 LINE_MODE_CHIP_NAME,
625 NUM_LINE_MODES, 632 NUM_LINE_MODES,
626}; 633};
627 634
@@ -651,53 +658,71 @@ static void parse_codec_mode(char *buf, struct hda_bus *bus,
651} 658}
652 659
653/* parse the contents after the other command tags, [pincfg], [verb], 660/* parse the contents after the other command tags, [pincfg], [verb],
654 * [hint] and [model] 661 * [vendor_id], [subsystem_id], [revision_id], [chip_name], [hint] and [model]
655 * just pass to the sysfs helper (only when any codec was specified) 662 * just pass to the sysfs helper (only when any codec was specified)
656 */ 663 */
657static void parse_pincfg_mode(char *buf, struct hda_bus *bus, 664static void parse_pincfg_mode(char *buf, struct hda_bus *bus,
658 struct hda_codec **codecp) 665 struct hda_codec **codecp)
659{ 666{
660 if (!*codecp)
661 return;
662 parse_user_pin_configs(*codecp, buf); 667 parse_user_pin_configs(*codecp, buf);
663} 668}
664 669
665static void parse_verb_mode(char *buf, struct hda_bus *bus, 670static void parse_verb_mode(char *buf, struct hda_bus *bus,
666 struct hda_codec **codecp) 671 struct hda_codec **codecp)
667{ 672{
668 if (!*codecp)
669 return;
670 parse_init_verbs(*codecp, buf); 673 parse_init_verbs(*codecp, buf);
671} 674}
672 675
673static void parse_hint_mode(char *buf, struct hda_bus *bus, 676static void parse_hint_mode(char *buf, struct hda_bus *bus,
674 struct hda_codec **codecp) 677 struct hda_codec **codecp)
675{ 678{
676 if (!*codecp)
677 return;
678 parse_hints(*codecp, buf); 679 parse_hints(*codecp, buf);
679} 680}
680 681
681static void parse_model_mode(char *buf, struct hda_bus *bus, 682static void parse_model_mode(char *buf, struct hda_bus *bus,
682 struct hda_codec **codecp) 683 struct hda_codec **codecp)
683{ 684{
684 if (!*codecp)
685 return;
686 kfree((*codecp)->modelname); 685 kfree((*codecp)->modelname);
687 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL); 686 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL);
688} 687}
689 688
689static void parse_chip_name_mode(char *buf, struct hda_bus *bus,
690 struct hda_codec **codecp)
691{
692 kfree((*codecp)->chip_name);
693 (*codecp)->chip_name = kstrdup(buf, GFP_KERNEL);
694}
695
696#define DEFINE_PARSE_ID_MODE(name) \
697static void parse_##name##_mode(char *buf, struct hda_bus *bus, \
698 struct hda_codec **codecp) \
699{ \
700 unsigned long val; \
701 if (!strict_strtoul(buf, 0, &val)) \
702 (*codecp)->name = val; \
703}
704
705DEFINE_PARSE_ID_MODE(vendor_id);
706DEFINE_PARSE_ID_MODE(subsystem_id);
707DEFINE_PARSE_ID_MODE(revision_id);
708
709
690struct hda_patch_item { 710struct hda_patch_item {
691 const char *tag; 711 const char *tag;
692 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc); 712 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc);
713 int need_codec;
693}; 714};
694 715
695static struct hda_patch_item patch_items[NUM_LINE_MODES] = { 716static struct hda_patch_item patch_items[NUM_LINE_MODES] = {
696 [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode }, 717 [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode, 0 },
697 [LINE_MODE_MODEL] = { "[model]", parse_model_mode }, 718 [LINE_MODE_MODEL] = { "[model]", parse_model_mode, 1 },
698 [LINE_MODE_VERB] = { "[verb]", parse_verb_mode }, 719 [LINE_MODE_VERB] = { "[verb]", parse_verb_mode, 1 },
699 [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode }, 720 [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode, 1 },
700 [LINE_MODE_HINT] = { "[hint]", parse_hint_mode }, 721 [LINE_MODE_HINT] = { "[hint]", parse_hint_mode, 1 },
722 [LINE_MODE_VENDOR_ID] = { "[vendor_id]", parse_vendor_id_mode, 1 },
723 [LINE_MODE_SUBSYSTEM_ID] = { "[subsystem_id]", parse_subsystem_id_mode, 1 },
724 [LINE_MODE_REVISION_ID] = { "[revision_id]", parse_revision_id_mode, 1 },
725 [LINE_MODE_CHIP_NAME] = { "[chip_name]", parse_chip_name_mode, 1 },
701}; 726};
702 727
703/* check the line starting with '[' -- change the parser mode accodingly */ 728/* check the line starting with '[' -- change the parser mode accodingly */
@@ -780,7 +805,8 @@ int snd_hda_load_patch(struct hda_bus *bus, const char *patch)
780 continue; 805 continue;
781 if (*buf == '[') 806 if (*buf == '[')
782 line_mode = parse_line_mode(buf, bus); 807 line_mode = parse_line_mode(buf, bus);
783 else if (patch_items[line_mode].parser) 808 else if (patch_items[line_mode].parser &&
809 (codec || !patch_items[line_mode].need_codec))
784 patch_items[line_mode].parser(buf, bus, &codec); 810 patch_items[line_mode].parser(buf, bus, &codec);
785 } 811 }
786 release_firmware(fw); 812 release_firmware(fw);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index ff6da6f386d1..d5c93ad852ee 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -125,6 +125,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
125 "{Intel, ICH9}," 125 "{Intel, ICH9},"
126 "{Intel, ICH10}," 126 "{Intel, ICH10},"
127 "{Intel, PCH}," 127 "{Intel, PCH},"
128 "{Intel, CPT},"
128 "{Intel, SCH}," 129 "{Intel, SCH},"
129 "{ATI, SB450}," 130 "{ATI, SB450},"
130 "{ATI, SB600}," 131 "{ATI, SB600},"
@@ -259,8 +260,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
259#define AZX_MAX_FRAG 32 260#define AZX_MAX_FRAG 32
260/* max buffer size - no h/w limit, you can increase as you like */ 261/* max buffer size - no h/w limit, you can increase as you like */
261#define AZX_MAX_BUF_SIZE (1024*1024*1024) 262#define AZX_MAX_BUF_SIZE (1024*1024*1024)
262/* max number of PCM devics per card */
263#define AZX_MAX_PCMS 8
264 263
265/* RIRB int mask: overrun[2], response[0] */ 264/* RIRB int mask: overrun[2], response[0] */
266#define RIRB_INT_RESPONSE 0x01 265#define RIRB_INT_RESPONSE 0x01
@@ -408,7 +407,7 @@ struct azx {
408 struct azx_dev *azx_dev; 407 struct azx_dev *azx_dev;
409 408
410 /* PCM */ 409 /* PCM */
411 struct snd_pcm *pcm[AZX_MAX_PCMS]; 410 struct snd_pcm *pcm[HDA_MAX_PCMS];
412 411
413 /* HD codec */ 412 /* HD codec */
414 unsigned short codec_mask; 413 unsigned short codec_mask;
@@ -449,6 +448,7 @@ struct azx {
449/* driver types */ 448/* driver types */
450enum { 449enum {
451 AZX_DRIVER_ICH, 450 AZX_DRIVER_ICH,
451 AZX_DRIVER_PCH,
452 AZX_DRIVER_SCH, 452 AZX_DRIVER_SCH,
453 AZX_DRIVER_ATI, 453 AZX_DRIVER_ATI,
454 AZX_DRIVER_ATIHDMI, 454 AZX_DRIVER_ATIHDMI,
@@ -463,6 +463,7 @@ enum {
463 463
464static char *driver_short_names[] __devinitdata = { 464static char *driver_short_names[] __devinitdata = {
465 [AZX_DRIVER_ICH] = "HDA Intel", 465 [AZX_DRIVER_ICH] = "HDA Intel",
466 [AZX_DRIVER_PCH] = "HDA Intel PCH",
466 [AZX_DRIVER_SCH] = "HDA Intel MID", 467 [AZX_DRIVER_SCH] = "HDA Intel MID",
467 [AZX_DRIVER_ATI] = "HDA ATI SB", 468 [AZX_DRIVER_ATI] = "HDA ATI SB",
468 [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI", 469 [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
@@ -968,8 +969,8 @@ static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev)
968 azx_dev->insufficient = 1; 969 azx_dev->insufficient = 1;
969 970
970 /* enable SIE */ 971 /* enable SIE */
971 azx_writeb(chip, INTCTL, 972 azx_writel(chip, INTCTL,
972 azx_readb(chip, INTCTL) | (1 << azx_dev->index)); 973 azx_readl(chip, INTCTL) | (1 << azx_dev->index));
973 /* set DMA start and interrupt mask */ 974 /* set DMA start and interrupt mask */
974 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) | 975 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
975 SD_CTL_DMA_START | SD_INT_MASK); 976 SD_CTL_DMA_START | SD_INT_MASK);
@@ -988,8 +989,8 @@ static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
988{ 989{
989 azx_stream_clear(chip, azx_dev); 990 azx_stream_clear(chip, azx_dev);
990 /* disable SIE */ 991 /* disable SIE */
991 azx_writeb(chip, INTCTL, 992 azx_writel(chip, INTCTL,
992 azx_readb(chip, INTCTL) & ~(1 << azx_dev->index)); 993 azx_readl(chip, INTCTL) & ~(1 << azx_dev->index));
993} 994}
994 995
995 996
@@ -1065,6 +1066,7 @@ static void azx_init_pci(struct azx *chip)
1065 0x01, NVIDIA_HDA_ENABLE_COHBIT); 1066 0x01, NVIDIA_HDA_ENABLE_COHBIT);
1066 break; 1067 break;
1067 case AZX_DRIVER_SCH: 1068 case AZX_DRIVER_SCH:
1069 case AZX_DRIVER_PCH:
1068 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); 1070 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
1069 if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { 1071 if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) {
1070 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, 1072 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC,
@@ -1350,7 +1352,7 @@ static void azx_bus_reset(struct hda_bus *bus)
1350 if (chip->initialized) { 1352 if (chip->initialized) {
1351 int i; 1353 int i;
1352 1354
1353 for (i = 0; i < AZX_MAX_PCMS; i++) 1355 for (i = 0; i < HDA_MAX_PCMS; i++)
1354 snd_pcm_suspend_all(chip->pcm[i]); 1356 snd_pcm_suspend_all(chip->pcm[i]);
1355 snd_hda_suspend(chip->bus); 1357 snd_hda_suspend(chip->bus);
1356 snd_hda_resume(chip->bus); 1358 snd_hda_resume(chip->bus);
@@ -1412,7 +1414,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1412 chip->codec_mask &= ~(1 << c); 1414 chip->codec_mask &= ~(1 << c);
1413 /* More badly, accessing to a non-existing 1415 /* More badly, accessing to a non-existing
1414 * codec often screws up the controller chip, 1416 * codec often screws up the controller chip,
1415 * and distrubs the further communications. 1417 * and disturbs the further communications.
1416 * Thus if an error occurs during probing, 1418 * Thus if an error occurs during probing,
1417 * better to reset the controller chip to 1419 * better to reset the controller chip to
1418 * get back to the sanity state. 1420 * get back to the sanity state.
@@ -1983,7 +1985,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
1983 int pcm_dev = cpcm->device; 1985 int pcm_dev = cpcm->device;
1984 int s, err; 1986 int s, err;
1985 1987
1986 if (pcm_dev >= AZX_MAX_PCMS) { 1988 if (pcm_dev >= HDA_MAX_PCMS) {
1987 snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n", 1989 snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n",
1988 pcm_dev); 1990 pcm_dev);
1989 return -EINVAL; 1991 return -EINVAL;
@@ -2139,7 +2141,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
2139 2141
2140 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2142 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2141 azx_clear_irq_pending(chip); 2143 azx_clear_irq_pending(chip);
2142 for (i = 0; i < AZX_MAX_PCMS; i++) 2144 for (i = 0; i < HDA_MAX_PCMS; i++)
2143 snd_pcm_suspend_all(chip->pcm[i]); 2145 snd_pcm_suspend_all(chip->pcm[i]);
2144 if (chip->initialized) 2146 if (chip->initialized)
2145 snd_hda_suspend(chip->bus); 2147 snd_hda_suspend(chip->bus);
@@ -2262,6 +2264,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
2262 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), 2264 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
2263 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), 2265 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
2264 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), 2266 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
2267 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
2265 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), 2268 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
2266 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), 2269 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
2267 {} 2270 {}
@@ -2418,6 +2421,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2418 if (bdl_pos_adj[dev] < 0) { 2421 if (bdl_pos_adj[dev] < 0) {
2419 switch (chip->driver_type) { 2422 switch (chip->driver_type) {
2420 case AZX_DRIVER_ICH: 2423 case AZX_DRIVER_ICH:
2424 case AZX_DRIVER_PCH:
2421 bdl_pos_adj[dev] = 1; 2425 bdl_pos_adj[dev] = 1;
2422 break; 2426 break;
2423 default: 2427 default:
@@ -2683,7 +2687,7 @@ static void __devexit azx_remove(struct pci_dev *pci)
2683} 2687}
2684 2688
2685/* PCI IDs */ 2689/* PCI IDs */
2686static struct pci_device_id azx_ids[] = { 2690static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2687 /* ICH 6..10 */ 2691 /* ICH 6..10 */
2688 { PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH }, 2692 { PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH },
2689 { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH }, 2693 { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH },
@@ -2696,6 +2700,8 @@ static struct pci_device_id azx_ids[] = {
2696 { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH }, 2700 { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH },
2697 /* PCH */ 2701 /* PCH */
2698 { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH }, 2702 { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH },
2703 /* CPT */
2704 { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH },
2699 /* SCH */ 2705 /* SCH */
2700 { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, 2706 { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH },
2701 /* ATI SB 450/600 */ 2707 /* ATI SB 450/600 */
@@ -2723,32 +2729,10 @@ static struct pci_device_id azx_ids[] = {
2723 /* ULI M5461 */ 2729 /* ULI M5461 */
2724 { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI }, 2730 { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI },
2725 /* NVIDIA MCP */ 2731 /* NVIDIA MCP */
2726 { PCI_DEVICE(0x10de, 0x026c), .driver_data = AZX_DRIVER_NVIDIA }, 2732 { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
2727 { PCI_DEVICE(0x10de, 0x0371), .driver_data = AZX_DRIVER_NVIDIA }, 2733 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2728 { PCI_DEVICE(0x10de, 0x03e4), .driver_data = AZX_DRIVER_NVIDIA }, 2734 .class_mask = 0xffffff,
2729 { PCI_DEVICE(0x10de, 0x03f0), .driver_data = AZX_DRIVER_NVIDIA }, 2735 .driver_data = AZX_DRIVER_NVIDIA },
2730 { PCI_DEVICE(0x10de, 0x044a), .driver_data = AZX_DRIVER_NVIDIA },
2731 { PCI_DEVICE(0x10de, 0x044b), .driver_data = AZX_DRIVER_NVIDIA },
2732 { PCI_DEVICE(0x10de, 0x055c), .driver_data = AZX_DRIVER_NVIDIA },
2733 { PCI_DEVICE(0x10de, 0x055d), .driver_data = AZX_DRIVER_NVIDIA },
2734 { PCI_DEVICE(0x10de, 0x0590), .driver_data = AZX_DRIVER_NVIDIA },
2735 { PCI_DEVICE(0x10de, 0x0774), .driver_data = AZX_DRIVER_NVIDIA },
2736 { PCI_DEVICE(0x10de, 0x0775), .driver_data = AZX_DRIVER_NVIDIA },
2737 { PCI_DEVICE(0x10de, 0x0776), .driver_data = AZX_DRIVER_NVIDIA },
2738 { PCI_DEVICE(0x10de, 0x0777), .driver_data = AZX_DRIVER_NVIDIA },
2739 { PCI_DEVICE(0x10de, 0x07fc), .driver_data = AZX_DRIVER_NVIDIA },
2740 { PCI_DEVICE(0x10de, 0x07fd), .driver_data = AZX_DRIVER_NVIDIA },
2741 { PCI_DEVICE(0x10de, 0x0ac0), .driver_data = AZX_DRIVER_NVIDIA },
2742 { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA },
2743 { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA },
2744 { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA },
2745 { PCI_DEVICE(0x10de, 0x0be2), .driver_data = AZX_DRIVER_NVIDIA },
2746 { PCI_DEVICE(0x10de, 0x0be3), .driver_data = AZX_DRIVER_NVIDIA },
2747 { PCI_DEVICE(0x10de, 0x0be4), .driver_data = AZX_DRIVER_NVIDIA },
2748 { PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA },
2749 { PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA },
2750 { PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA },
2751 { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA },
2752 /* Teradici */ 2736 /* Teradici */
2753 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, 2737 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
2754 /* Creative X-Fi (CA0110-IBG) */ 2738 /* Creative X-Fi (CA0110-IBG) */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 5778ae882b83..7cee364976ff 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -31,6 +31,7 @@
31 * in snd_hda_ctl_add(), so that this value won't appear in the outside. 31 * in snd_hda_ctl_add(), so that this value won't appear in the outside.
32 */ 32 */
33#define HDA_SUBDEV_NID_FLAG (1U << 31) 33#define HDA_SUBDEV_NID_FLAG (1U << 31)
34#define HDA_SUBDEV_AMP_FLAG (1U << 30)
34 35
35/* 36/*
36 * for mixer controls 37 * for mixer controls
@@ -42,7 +43,7 @@
42/* mono volume with index (index=0,1,...) (channel=1,2) */ 43/* mono volume with index (index=0,1,...) (channel=1,2) */
43#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 44#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
44 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 45 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
45 .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ 46 .subdevice = HDA_SUBDEV_AMP_FLAG, \
46 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 47 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
47 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 48 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
48 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ 49 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
@@ -63,7 +64,7 @@
63/* mono mute switch with index (index=0,1,...) (channel=1,2) */ 64/* mono mute switch with index (index=0,1,...) (channel=1,2) */
64#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 65#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
65 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 66 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
66 .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ 67 .subdevice = HDA_SUBDEV_AMP_FLAG, \
67 .info = snd_hda_mixer_amp_switch_info, \ 68 .info = snd_hda_mixer_amp_switch_info, \
68 .get = snd_hda_mixer_amp_switch_get, \ 69 .get = snd_hda_mixer_amp_switch_get, \
69 .put = snd_hda_mixer_amp_switch_put, \ 70 .put = snd_hda_mixer_amp_switch_put, \
@@ -81,7 +82,7 @@
81/* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */ 82/* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */
82#define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 83#define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
83 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 84 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
84 .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ 85 .subdevice = HDA_SUBDEV_AMP_FLAG, \
85 .info = snd_hda_mixer_amp_switch_info, \ 86 .info = snd_hda_mixer_amp_switch_info, \
86 .get = snd_hda_mixer_amp_switch_get, \ 87 .get = snd_hda_mixer_amp_switch_get, \
87 .put = snd_hda_mixer_amp_switch_put_beep, \ 88 .put = snd_hda_mixer_amp_switch_put_beep, \
@@ -464,13 +465,20 @@ u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid);
464u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); 465u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
465int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); 466int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
466 467
468/* flags for hda_nid_item */
469#define HDA_NID_ITEM_AMP (1<<0)
470
467struct hda_nid_item { 471struct hda_nid_item {
468 struct snd_kcontrol *kctl; 472 struct snd_kcontrol *kctl;
473 unsigned int index;
469 hda_nid_t nid; 474 hda_nid_t nid;
475 unsigned short flags;
470}; 476};
471 477
472int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, 478int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
473 struct snd_kcontrol *kctl); 479 struct snd_kcontrol *kctl);
480int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
481 unsigned int index, hda_nid_t nid);
474void snd_hda_ctls_clear(struct hda_codec *codec); 482void snd_hda_ctls_clear(struct hda_codec *codec);
475 483
476/* 484/*
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index c9afc04adac8..f97d35de66c4 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -61,18 +61,29 @@ static const char *get_wid_type_name(unsigned int wid_value)
61 return "UNKNOWN Widget"; 61 return "UNKNOWN Widget";
62} 62}
63 63
64static void print_nid_mixers(struct snd_info_buffer *buffer, 64static void print_nid_array(struct snd_info_buffer *buffer,
65 struct hda_codec *codec, hda_nid_t nid) 65 struct hda_codec *codec, hda_nid_t nid,
66 struct snd_array *array)
66{ 67{
67 int i; 68 int i;
68 struct hda_nid_item *items = codec->mixers.list; 69 struct hda_nid_item *items = array->list, *item;
69 struct snd_kcontrol *kctl; 70 struct snd_kcontrol *kctl;
70 for (i = 0; i < codec->mixers.used; i++) { 71 for (i = 0; i < array->used; i++) {
71 if (items[i].nid == nid) { 72 item = &items[i];
72 kctl = items[i].kctl; 73 if (item->nid == nid) {
74 kctl = item->kctl;
73 snd_iprintf(buffer, 75 snd_iprintf(buffer,
74 " Control: name=\"%s\", index=%i, device=%i\n", 76 " Control: name=\"%s\", index=%i, device=%i\n",
75 kctl->id.name, kctl->id.index, kctl->id.device); 77 kctl->id.name, kctl->id.index + item->index,
78 kctl->id.device);
79 if (item->flags & HDA_NID_ITEM_AMP)
80 snd_iprintf(buffer,
81 " ControlAmp: chs=%lu, dir=%s, "
82 "idx=%lu, ofs=%lu\n",
83 get_amp_channels(kctl),
84 get_amp_direction(kctl) ? "Out" : "In",
85 get_amp_index(kctl),
86 get_amp_offset(kctl));
76 } 87 }
77 } 88 }
78} 89}
@@ -528,7 +539,8 @@ static void print_gpio(struct snd_info_buffer *buffer,
528 (data & (1<<i)) ? 1 : 0, 539 (data & (1<<i)) ? 1 : 0,
529 (unsol & (1<<i)) ? 1 : 0); 540 (unsol & (1<<i)) ? 1 : 0);
530 /* FIXME: add GPO and GPI pin information */ 541 /* FIXME: add GPO and GPI pin information */
531 print_nid_mixers(buffer, codec, nid); 542 print_nid_array(buffer, codec, nid, &codec->mixers);
543 print_nid_array(buffer, codec, nid, &codec->nids);
532} 544}
533 545
534static void print_codec_info(struct snd_info_entry *entry, 546static void print_codec_info(struct snd_info_entry *entry,
@@ -608,7 +620,8 @@ static void print_codec_info(struct snd_info_entry *entry,
608 snd_iprintf(buffer, " CP"); 620 snd_iprintf(buffer, " CP");
609 snd_iprintf(buffer, "\n"); 621 snd_iprintf(buffer, "\n");
610 622
611 print_nid_mixers(buffer, codec, nid); 623 print_nid_array(buffer, codec, nid, &codec->mixers);
624 print_nid_array(buffer, codec, nid, &codec->nids);
612 print_nid_pcms(buffer, codec, nid); 625 print_nid_pcms(buffer, codec, nid);
613 626
614 /* volume knob is a special widget that always have connection 627 /* volume knob is a special widget that always have connection
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 69a941c7b158..e6d1bdff1b6e 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -174,6 +174,7 @@ static struct snd_kcontrol_new ad_beep_mixer[] = {
174static int ad198x_build_controls(struct hda_codec *codec) 174static int ad198x_build_controls(struct hda_codec *codec)
175{ 175{
176 struct ad198x_spec *spec = codec->spec; 176 struct ad198x_spec *spec = codec->spec;
177 struct snd_kcontrol *kctl;
177 unsigned int i; 178 unsigned int i;
178 int err; 179 int err;
179 180
@@ -208,9 +209,7 @@ static int ad198x_build_controls(struct hda_codec *codec)
208 if (!kctl) 209 if (!kctl)
209 return -ENOMEM; 210 return -ENOMEM;
210 kctl->private_value = spec->beep_amp; 211 kctl->private_value = spec->beep_amp;
211 err = snd_hda_ctl_add(codec, 212 err = snd_hda_ctl_add(codec, 0, kctl);
212 get_amp_nid_(spec->beep_amp),
213 kctl);
214 if (err < 0) 213 if (err < 0)
215 return err; 214 return err;
216 } 215 }
@@ -239,6 +238,27 @@ static int ad198x_build_controls(struct hda_codec *codec)
239 } 238 }
240 239
241 ad198x_free_kctls(codec); /* no longer needed */ 240 ad198x_free_kctls(codec); /* no longer needed */
241
242 /* assign Capture Source enums to NID */
243 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
244 if (!kctl)
245 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
246 for (i = 0; kctl && i < kctl->count; i++) {
247 err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]);
248 if (err < 0)
249 return err;
250 }
251
252 /* assign IEC958 enums to NID */
253 kctl = snd_hda_find_mixer_ctl(codec,
254 SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source");
255 if (kctl) {
256 err = snd_hda_add_nid(codec, kctl, 0,
257 spec->multiout.dig_out_nid);
258 if (err < 0)
259 return err;
260 }
261
242 return 0; 262 return 0;
243} 263}
244 264
@@ -421,6 +441,11 @@ static int ad198x_build_pcms(struct hda_codec *codec)
421 return 0; 441 return 0;
422} 442}
423 443
444static inline void ad198x_shutup(struct hda_codec *codec)
445{
446 snd_hda_shutup_pins(codec);
447}
448
424static void ad198x_free_kctls(struct hda_codec *codec) 449static void ad198x_free_kctls(struct hda_codec *codec)
425{ 450{
426 struct ad198x_spec *spec = codec->spec; 451 struct ad198x_spec *spec = codec->spec;
@@ -434,6 +459,46 @@ static void ad198x_free_kctls(struct hda_codec *codec)
434 snd_array_free(&spec->kctls); 459 snd_array_free(&spec->kctls);
435} 460}
436 461
462static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
463 hda_nid_t hp)
464{
465 struct ad198x_spec *spec = codec->spec;
466 snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
467 !spec->inv_eapd ? 0x00 : 0x02);
468 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
469 !spec->inv_eapd ? 0x00 : 0x02);
470}
471
472static void ad198x_power_eapd(struct hda_codec *codec)
473{
474 /* We currently only handle front, HP */
475 switch (codec->vendor_id) {
476 case 0x11d41882:
477 case 0x11d4882a:
478 case 0x11d41884:
479 case 0x11d41984:
480 case 0x11d41883:
481 case 0x11d4184a:
482 case 0x11d4194a:
483 case 0x11d4194b:
484 ad198x_power_eapd_write(codec, 0x12, 0x11);
485 break;
486 case 0x11d41981:
487 case 0x11d41983:
488 ad198x_power_eapd_write(codec, 0x05, 0x06);
489 break;
490 case 0x11d41986:
491 ad198x_power_eapd_write(codec, 0x1b, 0x1a);
492 break;
493 case 0x11d41988:
494 case 0x11d4198b:
495 case 0x11d4989a:
496 case 0x11d4989b:
497 ad198x_power_eapd_write(codec, 0x29, 0x22);
498 break;
499 }
500}
501
437static void ad198x_free(struct hda_codec *codec) 502static void ad198x_free(struct hda_codec *codec)
438{ 503{
439 struct ad198x_spec *spec = codec->spec; 504 struct ad198x_spec *spec = codec->spec;
@@ -441,11 +506,29 @@ static void ad198x_free(struct hda_codec *codec)
441 if (!spec) 506 if (!spec)
442 return; 507 return;
443 508
509 ad198x_shutup(codec);
444 ad198x_free_kctls(codec); 510 ad198x_free_kctls(codec);
445 kfree(spec); 511 kfree(spec);
446 snd_hda_detach_beep_device(codec); 512 snd_hda_detach_beep_device(codec);
447} 513}
448 514
515#ifdef SND_HDA_NEEDS_RESUME
516static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
517{
518 ad198x_shutup(codec);
519 ad198x_power_eapd(codec);
520 return 0;
521}
522
523static int ad198x_resume(struct hda_codec *codec)
524{
525 ad198x_init(codec);
526 snd_hda_codec_resume_amp(codec);
527 snd_hda_codec_resume_cache(codec);
528 return 0;
529}
530#endif
531
449static struct hda_codec_ops ad198x_patch_ops = { 532static struct hda_codec_ops ad198x_patch_ops = {
450 .build_controls = ad198x_build_controls, 533 .build_controls = ad198x_build_controls,
451 .build_pcms = ad198x_build_pcms, 534 .build_pcms = ad198x_build_pcms,
@@ -454,6 +537,11 @@ static struct hda_codec_ops ad198x_patch_ops = {
454#ifdef CONFIG_SND_HDA_POWER_SAVE 537#ifdef CONFIG_SND_HDA_POWER_SAVE
455 .check_power_status = ad198x_check_power_status, 538 .check_power_status = ad198x_check_power_status,
456#endif 539#endif
540#ifdef SND_HDA_NEEDS_RESUME
541 .suspend = ad198x_suspend,
542 .resume = ad198x_resume,
543#endif
544 .reboot_notify = ad198x_shutup,
457}; 545};
458 546
459 547
@@ -701,6 +789,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
701 { 789 {
702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 790 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
703 .name = "External Amplifier", 791 .name = "External Amplifier",
792 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
704 .info = ad198x_eapd_info, 793 .info = ad198x_eapd_info,
705 .get = ad198x_eapd_get, 794 .get = ad198x_eapd_get,
706 .put = ad198x_eapd_put, 795 .put = ad198x_eapd_put,
@@ -808,6 +897,7 @@ static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
808 { 897 {
809 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 898 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
810 .name = "Master Playback Switch", 899 .name = "Master Playback Switch",
900 .subdevice = HDA_SUBDEV_AMP_FLAG,
811 .info = snd_hda_mixer_amp_switch_info, 901 .info = snd_hda_mixer_amp_switch_info,
812 .get = snd_hda_mixer_amp_switch_get, 902 .get = snd_hda_mixer_amp_switch_get,
813 .put = ad1986a_hp_master_sw_put, 903 .put = ad1986a_hp_master_sw_put,
@@ -1008,7 +1098,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1008 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK), 1098 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
1009 SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK), 1099 SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
1010 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK), 1100 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
1011 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD), 1101 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK),
1012 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), 1102 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
1013 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), 1103 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
1014 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50), 1104 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50),
@@ -1612,6 +1702,7 @@ static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1612 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), 1702 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1613 { 1703 {
1614 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1704 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1705 .subdevice = HDA_SUBDEV_NID_FLAG | 0x05,
1615 .name = "Master Playback Switch", 1706 .name = "Master Playback Switch",
1616 .info = ad198x_eapd_info, 1707 .info = ad198x_eapd_info,
1617 .get = ad198x_eapd_get, 1708 .get = ad198x_eapd_get,
@@ -2136,6 +2227,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2136 { 2227 {
2137 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2228 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2138 .name = "External Amplifier", 2229 .name = "External Amplifier",
2230 .subdevice = HDA_SUBDEV_NID_FLAG | 0x12,
2139 .info = ad198x_eapd_info, 2231 .info = ad198x_eapd_info,
2140 .get = ad198x_eapd_get, 2232 .get = ad198x_eapd_get,
2141 .put = ad198x_eapd_put, 2233 .put = ad198x_eapd_put,
@@ -2257,6 +2349,7 @@ static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2257 { 2349 {
2258 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2350 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2259 .name = "IEC958 Playback Source", 2351 .name = "IEC958 Playback Source",
2352 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
2260 .info = ad1988_spdif_playback_source_info, 2353 .info = ad1988_spdif_playback_source_info,
2261 .get = ad1988_spdif_playback_source_get, 2354 .get = ad1988_spdif_playback_source_get,
2262 .put = ad1988_spdif_playback_source_put, 2355 .put = ad1988_spdif_playback_source_put,
@@ -2372,6 +2465,12 @@ static struct hda_verb ad1988_spdif_init_verbs[] = {
2372 { } 2465 { }
2373}; 2466};
2374 2467
2468static struct hda_verb ad1988_spdif_in_init_verbs[] = {
2469 /* unmute SPDIF input pin */
2470 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2471 { }
2472};
2473
2375/* AD1989 has no ADC -> SPDIF route */ 2474/* AD1989 has no ADC -> SPDIF route */
2376static struct hda_verb ad1989_spdif_init_verbs[] = { 2475static struct hda_verb ad1989_spdif_init_verbs[] = {
2377 /* SPDIF-1 out pin */ 2476 /* SPDIF-1 out pin */
@@ -2589,7 +2688,7 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name,
2589 if (! knew->name) 2688 if (! knew->name)
2590 return -ENOMEM; 2689 return -ENOMEM;
2591 if (get_amp_nid_(val)) 2690 if (get_amp_nid_(val))
2592 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 2691 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
2593 knew->private_value = val; 2692 knew->private_value = val;
2594 return 0; 2693 return 0;
2595} 2694}
@@ -3107,8 +3206,11 @@ static int patch_ad1988(struct hda_codec *codec)
3107 ad1988_spdif_init_verbs; 3206 ad1988_spdif_init_verbs;
3108 } 3207 }
3109 } 3208 }
3110 if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) 3209 if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) {
3111 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers; 3210 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
3211 spec->init_verbs[spec->num_init_verbs++] =
3212 ad1988_spdif_in_init_verbs;
3213 }
3112 3214
3113 codec->patch_ops = ad198x_patch_ops; 3215 codec->patch_ops = ad198x_patch_ops;
3114 switch (board_config) { 3216 switch (board_config) {
@@ -3747,6 +3849,7 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3747 { 3849 {
3748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3850 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3749 .name = "Master Playback Switch", 3851 .name = "Master Playback Switch",
3852 .subdevice = HDA_SUBDEV_AMP_FLAG,
3750 .info = snd_hda_mixer_amp_switch_info, 3853 .info = snd_hda_mixer_amp_switch_info,
3751 .get = snd_hda_mixer_amp_switch_get, 3854 .get = snd_hda_mixer_amp_switch_get,
3752 .put = ad1884a_mobile_master_sw_put, 3855 .put = ad1884a_mobile_master_sw_put,
@@ -3775,6 +3878,7 @@ static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3775 { 3878 {
3776 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3879 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3777 .name = "Master Playback Switch", 3880 .name = "Master Playback Switch",
3881 .subdevice = HDA_SUBDEV_AMP_FLAG,
3778 .info = snd_hda_mixer_amp_switch_info, 3882 .info = snd_hda_mixer_amp_switch_info,
3779 .get = snd_hda_mixer_amp_switch_get, 3883 .get = snd_hda_mixer_amp_switch_get,
3780 .put = ad1884a_mobile_master_sw_put, 3884 .put = ad1884a_mobile_master_sw_put,
@@ -4116,6 +4220,7 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4116/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 4220/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4117 { 4221 {
4118 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4222 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4223 .subdevice = HDA_SUBDEV_AMP_FLAG,
4119 .name = "Master Playback Switch", 4224 .name = "Master Playback Switch",
4120 .info = snd_hda_mixer_amp_switch_info, 4225 .info = snd_hda_mixer_amp_switch_info,
4121 .get = snd_hda_mixer_amp_switch_get, 4226 .get = snd_hda_mixer_amp_switch_get,
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index fe0423c39598..7de782a5b8f4 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -501,7 +501,8 @@ static int add_mute(struct hda_codec *codec, const char *name, int index,
501 knew.private_value = pval; 501 knew.private_value = pval;
502 snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]); 502 snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]);
503 *kctlp = snd_ctl_new1(&knew, codec); 503 *kctlp = snd_ctl_new1(&knew, codec);
504 return snd_hda_ctl_add(codec, get_amp_nid_(pval), *kctlp); 504 (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
505 return snd_hda_ctl_add(codec, 0, *kctlp);
505} 506}
506 507
507static int add_volume(struct hda_codec *codec, const char *name, 508static int add_volume(struct hda_codec *codec, const char *name,
@@ -514,7 +515,8 @@ static int add_volume(struct hda_codec *codec, const char *name,
514 knew.private_value = pval; 515 knew.private_value = pval;
515 snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]); 516 snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]);
516 *kctlp = snd_ctl_new1(&knew, codec); 517 *kctlp = snd_ctl_new1(&knew, codec);
517 return snd_hda_ctl_add(codec, get_amp_nid_(pval), *kctlp); 518 (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
519 return snd_hda_ctl_add(codec, 0, *kctlp);
518} 520}
519 521
520static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac) 522static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac)
@@ -751,6 +753,7 @@ static int build_input(struct hda_codec *codec)
751 spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol); 753 spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol);
752 for (i = 0; i < 2; i++) { 754 for (i = 0; i < 2; i++) {
753 struct snd_kcontrol *kctl; 755 struct snd_kcontrol *kctl;
756 int n;
754 if (!spec->capture_bind[i]) 757 if (!spec->capture_bind[i])
755 return -ENOMEM; 758 return -ENOMEM;
756 kctl = snd_ctl_new1(&cs_capture_ctls[i], codec); 759 kctl = snd_ctl_new1(&cs_capture_ctls[i], codec);
@@ -760,6 +763,13 @@ static int build_input(struct hda_codec *codec)
760 err = snd_hda_ctl_add(codec, 0, kctl); 763 err = snd_hda_ctl_add(codec, 0, kctl);
761 if (err < 0) 764 if (err < 0)
762 return err; 765 return err;
766 for (n = 0; n < AUTO_PIN_LAST; n++) {
767 if (!spec->adc_nid[n])
768 continue;
769 err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[i]);
770 if (err < 0)
771 return err;
772 }
763 } 773 }
764 774
765 if (spec->num_inputs > 1 && !spec->mic_detect) { 775 if (spec->num_inputs > 1 && !spec->mic_detect) {
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index a45c1169762b..ff60908f4554 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -315,7 +315,8 @@ static struct hda_verb cmi9880_allout_init[] = {
315static int cmi9880_build_controls(struct hda_codec *codec) 315static int cmi9880_build_controls(struct hda_codec *codec)
316{ 316{
317 struct cmi_spec *spec = codec->spec; 317 struct cmi_spec *spec = codec->spec;
318 int err; 318 struct snd_kcontrol *kctl;
319 int i, err;
319 320
320 err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer); 321 err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer);
321 if (err < 0) 322 if (err < 0)
@@ -340,6 +341,14 @@ static int cmi9880_build_controls(struct hda_codec *codec)
340 if (err < 0) 341 if (err < 0)
341 return err; 342 return err;
342 } 343 }
344
345 /* assign Capture Source enums to NID */
346 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
347 for (i = 0; kctl && i < kctl->count; i++) {
348 err = snd_hda_add_nid(codec, kctl, i, spec->adc_nids[i]);
349 if (err < 0)
350 return err;
351 }
343 return 0; 352 return 0;
344} 353}
345 354
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index c578c28f368e..194a28c54992 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -42,10 +42,12 @@
42 42
43/* Conexant 5051 specific */ 43/* Conexant 5051 specific */
44 44
45#define CXT5051_SPDIF_OUT 0x1C 45#define CXT5051_SPDIF_OUT 0x12
46#define CXT5051_PORTB_EVENT 0x38 46#define CXT5051_PORTB_EVENT 0x38
47#define CXT5051_PORTC_EVENT 0x39 47#define CXT5051_PORTC_EVENT 0x39
48 48
49#define AUTO_MIC_PORTB (1 << 1)
50#define AUTO_MIC_PORTC (1 << 2)
49 51
50struct conexant_jack { 52struct conexant_jack {
51 53
@@ -74,7 +76,7 @@ struct conexant_spec {
74 */ 76 */
75 unsigned int cur_eapd; 77 unsigned int cur_eapd;
76 unsigned int hp_present; 78 unsigned int hp_present;
77 unsigned int no_auto_mic; 79 unsigned int auto_mic;
78 unsigned int need_dac_fix; 80 unsigned int need_dac_fix;
79 81
80 /* capture */ 82 /* capture */
@@ -111,8 +113,23 @@ struct conexant_spec {
111 113
112 unsigned int dell_automute; 114 unsigned int dell_automute;
113 unsigned int port_d_mode; 115 unsigned int port_d_mode;
114 unsigned char ext_mic_bias; 116 unsigned int dell_vostro:1;
115 unsigned int dell_vostro; 117 unsigned int ideapad:1;
118
119 unsigned int ext_mic_present;
120 unsigned int recording;
121 void (*capture_prepare)(struct hda_codec *codec);
122 void (*capture_cleanup)(struct hda_codec *codec);
123
124 /* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors)
125 * through the microphone jack.
126 * When the user enables this through a mixer switch, both internal and
127 * external microphones are disabled. Gain is fixed at 0dB. In this mode,
128 * we also allow the bias to be configured through a separate mixer
129 * control. */
130 unsigned int dc_enable;
131 unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */
132 unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
116}; 133};
117 134
118static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, 135static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -185,6 +202,8 @@ static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
185 struct snd_pcm_substream *substream) 202 struct snd_pcm_substream *substream)
186{ 203{
187 struct conexant_spec *spec = codec->spec; 204 struct conexant_spec *spec = codec->spec;
205 if (spec->capture_prepare)
206 spec->capture_prepare(codec);
188 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 207 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
189 stream_tag, 0, format); 208 stream_tag, 0, format);
190 return 0; 209 return 0;
@@ -196,6 +215,8 @@ static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
196{ 215{
197 struct conexant_spec *spec = codec->spec; 216 struct conexant_spec *spec = codec->spec;
198 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); 217 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
218 if (spec->capture_cleanup)
219 spec->capture_cleanup(codec);
199 return 0; 220 return 0;
200} 221}
201 222
@@ -1585,6 +1606,11 @@ static void cxt5051_update_speaker(struct hda_codec *codec)
1585{ 1606{
1586 struct conexant_spec *spec = codec->spec; 1607 struct conexant_spec *spec = codec->spec;
1587 unsigned int pinctl; 1608 unsigned int pinctl;
1609 /* headphone pin */
1610 pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0;
1611 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1612 pinctl);
1613 /* speaker pin */
1588 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; 1614 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1589 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1615 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1590 pinctl); 1616 pinctl);
@@ -1608,7 +1634,7 @@ static void cxt5051_portb_automic(struct hda_codec *codec)
1608 struct conexant_spec *spec = codec->spec; 1634 struct conexant_spec *spec = codec->spec;
1609 unsigned int present; 1635 unsigned int present;
1610 1636
1611 if (spec->no_auto_mic) 1637 if (!(spec->auto_mic & AUTO_MIC_PORTB))
1612 return; 1638 return;
1613 present = snd_hda_jack_detect(codec, 0x17); 1639 present = snd_hda_jack_detect(codec, 0x17);
1614 snd_hda_codec_write(codec, 0x14, 0, 1640 snd_hda_codec_write(codec, 0x14, 0,
@@ -1623,7 +1649,7 @@ static void cxt5051_portc_automic(struct hda_codec *codec)
1623 unsigned int present; 1649 unsigned int present;
1624 hda_nid_t new_adc; 1650 hda_nid_t new_adc;
1625 1651
1626 if (spec->no_auto_mic) 1652 if (!(spec->auto_mic & AUTO_MIC_PORTC))
1627 return; 1653 return;
1628 present = snd_hda_jack_detect(codec, 0x18); 1654 present = snd_hda_jack_detect(codec, 0x18);
1629 if (present) 1655 if (present)
@@ -1669,13 +1695,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1669 conexant_report_jack(codec, nid); 1695 conexant_report_jack(codec, nid);
1670} 1696}
1671 1697
1672static struct snd_kcontrol_new cxt5051_mixers[] = { 1698static struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1673 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1674 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1675 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1676 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1677 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1678 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1679 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 1699 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1680 { 1700 {
1681 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1701 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1685,7 +1705,16 @@ static struct snd_kcontrol_new cxt5051_mixers[] = {
1685 .put = cxt5051_hp_master_sw_put, 1705 .put = cxt5051_hp_master_sw_put,
1686 .private_value = 0x1a, 1706 .private_value = 0x1a,
1687 }, 1707 },
1708 {}
1709};
1688 1710
1711static struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1712 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1713 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1714 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1715 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1716 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1717 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1689 {} 1718 {}
1690}; 1719};
1691 1720
@@ -1694,32 +1723,26 @@ static struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1694 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1723 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1695 HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT), 1724 HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT),
1696 HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT), 1725 HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT),
1697 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1698 {
1699 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1700 .name = "Master Playback Switch",
1701 .info = cxt_eapd_info,
1702 .get = cxt_eapd_get,
1703 .put = cxt5051_hp_master_sw_put,
1704 .private_value = 0x1a,
1705 },
1706
1707 {} 1726 {}
1708}; 1727};
1709 1728
1710static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = { 1729static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1711 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x00, HDA_INPUT), 1730 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT),
1712 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x00, HDA_INPUT), 1731 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT),
1713 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 1732 {}
1714 { 1733};
1715 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1716 .name = "Master Playback Switch",
1717 .info = cxt_eapd_info,
1718 .get = cxt_eapd_get,
1719 .put = cxt5051_hp_master_sw_put,
1720 .private_value = 0x1a,
1721 },
1722 1734
1735static struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1736 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT),
1737 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT),
1738 {}
1739};
1740
1741static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1742 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1743 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1744 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1745 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1723 {} 1746 {}
1724}; 1747};
1725 1748
@@ -1748,8 +1771,6 @@ static struct hda_verb cxt5051_init_verbs[] = {
1748 /* EAPD */ 1771 /* EAPD */
1749 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1772 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1750 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1773 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1751 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1752 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1753 { } /* end */ 1774 { } /* end */
1754}; 1775};
1755 1776
@@ -1775,7 +1796,6 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1775 /* EAPD */ 1796 /* EAPD */
1776 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1797 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1777 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1798 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1778 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1779 { } /* end */ 1799 { } /* end */
1780}; 1800};
1781 1801
@@ -1807,17 +1827,60 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1807 /* EAPD */ 1827 /* EAPD */
1808 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1828 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1809 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1829 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1810 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1811 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1812 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1830 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1813 { } /* end */ 1831 { } /* end */
1814}; 1832};
1815 1833
1834static struct hda_verb cxt5051_f700_init_verbs[] = {
1835 /* Line in, Mic */
1836 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1837 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1838 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1839 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1840 /* SPK */
1841 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1842 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1843 /* HP, Amp */
1844 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1845 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1846 /* DAC1 */
1847 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1848 /* Record selector: Int mic */
1849 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1850 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1851 /* SPDIF route: PCM */
1852 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1853 /* EAPD */
1854 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1855 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1856 { } /* end */
1857};
1858
1859static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1860 unsigned int event)
1861{
1862 snd_hda_codec_write(codec, nid, 0,
1863 AC_VERB_SET_UNSOLICITED_ENABLE,
1864 AC_USRSP_EN | event);
1865#ifdef CONFIG_SND_HDA_INPUT_JACK
1866 conexant_add_jack(codec, nid, SND_JACK_MICROPHONE);
1867 conexant_report_jack(codec, nid);
1868#endif
1869}
1870
1816/* initialize jack-sensing, too */ 1871/* initialize jack-sensing, too */
1817static int cxt5051_init(struct hda_codec *codec) 1872static int cxt5051_init(struct hda_codec *codec)
1818{ 1873{
1874 struct conexant_spec *spec = codec->spec;
1875
1819 conexant_init(codec); 1876 conexant_init(codec);
1820 conexant_init_jacks(codec); 1877 conexant_init_jacks(codec);
1878
1879 if (spec->auto_mic & AUTO_MIC_PORTB)
1880 cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT);
1881 if (spec->auto_mic & AUTO_MIC_PORTC)
1882 cxt5051_init_mic_port(codec, 0x18, CXT5051_PORTC_EVENT);
1883
1821 if (codec->patch_ops.unsol_event) { 1884 if (codec->patch_ops.unsol_event) {
1822 cxt5051_hp_automute(codec); 1885 cxt5051_hp_automute(codec);
1823 cxt5051_portb_automic(codec); 1886 cxt5051_portb_automic(codec);
@@ -1832,6 +1895,8 @@ enum {
1832 CXT5051_HP, /* no docking */ 1895 CXT5051_HP, /* no docking */
1833 CXT5051_HP_DV6736, /* HP without mic switch */ 1896 CXT5051_HP_DV6736, /* HP without mic switch */
1834 CXT5051_LENOVO_X200, /* Lenovo X200 laptop */ 1897 CXT5051_LENOVO_X200, /* Lenovo X200 laptop */
1898 CXT5051_F700, /* HP Compaq Presario F700 */
1899 CXT5051_TOSHIBA, /* Toshiba M300 & co */
1835 CXT5051_MODELS 1900 CXT5051_MODELS
1836}; 1901};
1837 1902
@@ -1840,11 +1905,15 @@ static const char *cxt5051_models[CXT5051_MODELS] = {
1840 [CXT5051_HP] = "hp", 1905 [CXT5051_HP] = "hp",
1841 [CXT5051_HP_DV6736] = "hp-dv6736", 1906 [CXT5051_HP_DV6736] = "hp-dv6736",
1842 [CXT5051_LENOVO_X200] = "lenovo-x200", 1907 [CXT5051_LENOVO_X200] = "lenovo-x200",
1908 [CXT5051_F700] = "hp-700",
1909 [CXT5051_TOSHIBA] = "toshiba",
1843}; 1910};
1844 1911
1845static struct snd_pci_quirk cxt5051_cfg_tbl[] = { 1912static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1846 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), 1913 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1847 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP), 1914 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1915 SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
1916 SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba M30x", CXT5051_TOSHIBA),
1848 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", 1917 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1849 CXT5051_LAPTOP), 1918 CXT5051_LAPTOP),
1850 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), 1919 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
@@ -1872,8 +1941,9 @@ static int patch_cxt5051(struct hda_codec *codec)
1872 spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT; 1941 spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT;
1873 spec->num_adc_nids = 1; /* not 2; via auto-mic switch */ 1942 spec->num_adc_nids = 1; /* not 2; via auto-mic switch */
1874 spec->adc_nids = cxt5051_adc_nids; 1943 spec->adc_nids = cxt5051_adc_nids;
1875 spec->num_mixers = 1; 1944 spec->num_mixers = 2;
1876 spec->mixers[0] = cxt5051_mixers; 1945 spec->mixers[0] = cxt5051_capture_mixers;
1946 spec->mixers[1] = cxt5051_playback_mixers;
1877 spec->num_init_verbs = 1; 1947 spec->num_init_verbs = 1;
1878 spec->init_verbs[0] = cxt5051_init_verbs; 1948 spec->init_verbs[0] = cxt5051_init_verbs;
1879 spec->spdif_route = 0; 1949 spec->spdif_route = 0;
@@ -1887,6 +1957,7 @@ static int patch_cxt5051(struct hda_codec *codec)
1887 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, 1957 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1888 cxt5051_models, 1958 cxt5051_models,
1889 cxt5051_cfg_tbl); 1959 cxt5051_cfg_tbl);
1960 spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC;
1890 switch (board_config) { 1961 switch (board_config) {
1891 case CXT5051_HP: 1962 case CXT5051_HP:
1892 spec->mixers[0] = cxt5051_hp_mixers; 1963 spec->mixers[0] = cxt5051_hp_mixers;
@@ -1894,11 +1965,20 @@ static int patch_cxt5051(struct hda_codec *codec)
1894 case CXT5051_HP_DV6736: 1965 case CXT5051_HP_DV6736:
1895 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs; 1966 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
1896 spec->mixers[0] = cxt5051_hp_dv6736_mixers; 1967 spec->mixers[0] = cxt5051_hp_dv6736_mixers;
1897 spec->no_auto_mic = 1; 1968 spec->auto_mic = 0;
1898 break; 1969 break;
1899 case CXT5051_LENOVO_X200: 1970 case CXT5051_LENOVO_X200:
1900 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; 1971 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
1901 break; 1972 break;
1973 case CXT5051_F700:
1974 spec->init_verbs[0] = cxt5051_f700_init_verbs;
1975 spec->mixers[0] = cxt5051_f700_mixers;
1976 spec->auto_mic = 0;
1977 break;
1978 case CXT5051_TOSHIBA:
1979 spec->mixers[0] = cxt5051_toshiba_mixers;
1980 spec->auto_mic = AUTO_MIC_PORTB;
1981 break;
1902 } 1982 }
1903 1983
1904 return 0; 1984 return 0;
@@ -1966,33 +2046,117 @@ static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1966 return 1; 2046 return 1;
1967} 2047}
1968 2048
2049static const struct hda_input_mux cxt5066_olpc_dc_bias = {
2050 .num_items = 3,
2051 .items = {
2052 { "Off", PIN_IN },
2053 { "50%", PIN_VREF50 },
2054 { "80%", PIN_VREF80 },
2055 },
2056};
2057
2058static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec)
2059{
2060 struct conexant_spec *spec = codec->spec;
2061 /* Even though port F is the DC input, the bias is controlled on port B.
2062 * we also leave that port as an active input (but unselected) in DC mode
2063 * just in case that is necessary to make the bias setting take effect. */
2064 return snd_hda_codec_write_cache(codec, 0x1a, 0,
2065 AC_VERB_SET_PIN_WIDGET_CONTROL,
2066 cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index);
2067}
2068
2069/* OLPC defers mic widget control until when capture is started because the
2070 * microphone LED comes on as soon as these settings are put in place. if we
2071 * did this before recording, it would give the false indication that recording
2072 * is happening when it is not. */
2073static void cxt5066_olpc_select_mic(struct hda_codec *codec)
2074{
2075 struct conexant_spec *spec = codec->spec;
2076 if (!spec->recording)
2077 return;
2078
2079 if (spec->dc_enable) {
2080 /* in DC mode we ignore presence detection and just use the jack
2081 * through our special DC port */
2082 const struct hda_verb enable_dc_mode[] = {
2083 /* disble internal mic, port C */
2084 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2085
2086 /* enable DC capture, port F */
2087 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2088 {},
2089 };
2090
2091 snd_hda_sequence_write(codec, enable_dc_mode);
2092 /* port B input disabled (and bias set) through the following call */
2093 cxt5066_set_olpc_dc_bias(codec);
2094 return;
2095 }
2096
2097 /* disable DC (port F) */
2098 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2099
2100 /* external mic, port B */
2101 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2102 spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0);
2103
2104 /* internal mic, port C */
2105 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2106 spec->ext_mic_present ? 0 : PIN_VREF80);
2107}
2108
1969/* toggle input of built-in and mic jack appropriately */ 2109/* toggle input of built-in and mic jack appropriately */
1970static void cxt5066_automic(struct hda_codec *codec) 2110static void cxt5066_olpc_automic(struct hda_codec *codec)
1971{ 2111{
1972 struct conexant_spec *spec = codec->spec; 2112 struct conexant_spec *spec = codec->spec;
2113 unsigned int present;
2114
2115 if (spec->dc_enable) /* don't do presence detection in DC mode */
2116 return;
2117
2118 present = snd_hda_codec_read(codec, 0x1a, 0,
2119 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2120 if (present)
2121 snd_printdd("CXT5066: external microphone detected\n");
2122 else
2123 snd_printdd("CXT5066: external microphone absent\n");
2124
2125 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2126 present ? 0 : 1);
2127 spec->ext_mic_present = !!present;
2128
2129 cxt5066_olpc_select_mic(codec);
2130}
2131
2132/* toggle input of built-in digital mic and mic jack appropriately */
2133static void cxt5066_vostro_automic(struct hda_codec *codec)
2134{
2135 unsigned int present;
2136
1973 struct hda_verb ext_mic_present[] = { 2137 struct hda_verb ext_mic_present[] = {
1974 /* enable external mic, port B */ 2138 /* enable external mic, port B */
1975 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias}, 2139 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1976 2140
1977 /* switch to external mic input */ 2141 /* switch to external mic input */
1978 {0x17, AC_VERB_SET_CONNECT_SEL, 0}, 2142 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2143 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
1979 2144
1980 /* disable internal mic, port C */ 2145 /* disable internal digital mic */
1981 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2146 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
1982 {} 2147 {}
1983 }; 2148 };
1984 static struct hda_verb ext_mic_absent[] = { 2149 static struct hda_verb ext_mic_absent[] = {
1985 /* enable internal mic, port C */ 2150 /* enable internal mic, port C */
1986 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2151 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1987 2152
1988 /* switch to internal mic input */ 2153 /* switch to internal mic input */
1989 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, 2154 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
1990 2155
1991 /* disable external mic, port B */ 2156 /* disable external mic, port B */
1992 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2157 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
1993 {} 2158 {}
1994 }; 2159 };
1995 unsigned int present;
1996 2160
1997 present = snd_hda_jack_detect(codec, 0x1a); 2161 present = snd_hda_jack_detect(codec, 0x1a);
1998 if (present) { 2162 if (present) {
@@ -2005,36 +2169,24 @@ static void cxt5066_automic(struct hda_codec *codec)
2005} 2169}
2006 2170
2007/* toggle input of built-in digital mic and mic jack appropriately */ 2171/* toggle input of built-in digital mic and mic jack appropriately */
2008static void cxt5066_vostro_automic(struct hda_codec *codec) 2172static void cxt5066_ideapad_automic(struct hda_codec *codec)
2009{ 2173{
2010 struct conexant_spec *spec = codec->spec;
2011 unsigned int present; 2174 unsigned int present;
2012 2175
2013 struct hda_verb ext_mic_present[] = { 2176 struct hda_verb ext_mic_present[] = {
2014 /* enable external mic, port B */
2015 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias},
2016
2017 /* switch to external mic input */
2018 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2019 {0x14, AC_VERB_SET_CONNECT_SEL, 0}, 2177 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2020 2178 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2021 /* disable internal digital mic */
2022 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2179 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2023 {} 2180 {}
2024 }; 2181 };
2025 static struct hda_verb ext_mic_absent[] = { 2182 static struct hda_verb ext_mic_absent[] = {
2026 /* enable internal mic, port C */
2027 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2028
2029 /* switch to internal mic input */
2030 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, 2183 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2031 2184 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2032 /* disable external mic, port B */ 2185 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2033 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2034 {} 2186 {}
2035 }; 2187 };
2036 2188
2037 present = snd_hda_jack_detect(codec, 0x1a); 2189 present = snd_hda_jack_detect(codec, 0x1b);
2038 if (present) { 2190 if (present) {
2039 snd_printdd("CXT5066: external microphone detected\n"); 2191 snd_printdd("CXT5066: external microphone detected\n");
2040 snd_hda_sequence_write(codec, ext_mic_present); 2192 snd_hda_sequence_write(codec, ext_mic_present);
@@ -2063,15 +2215,18 @@ static void cxt5066_hp_automute(struct hda_codec *codec)
2063} 2215}
2064 2216
2065/* unsolicited event for jack sensing */ 2217/* unsolicited event for jack sensing */
2066static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res) 2218static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res)
2067{ 2219{
2220 struct conexant_spec *spec = codec->spec;
2068 snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26); 2221 snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2069 switch (res >> 26) { 2222 switch (res >> 26) {
2070 case CONEXANT_HP_EVENT: 2223 case CONEXANT_HP_EVENT:
2071 cxt5066_hp_automute(codec); 2224 cxt5066_hp_automute(codec);
2072 break; 2225 break;
2073 case CONEXANT_MIC_EVENT: 2226 case CONEXANT_MIC_EVENT:
2074 cxt5066_automic(codec); 2227 /* ignore mic events in DC mode; we're always using the jack */
2228 if (!spec->dc_enable)
2229 cxt5066_olpc_automic(codec);
2075 break; 2230 break;
2076 } 2231 }
2077} 2232}
@@ -2090,6 +2245,20 @@ static void cxt5066_vostro_event(struct hda_codec *codec, unsigned int res)
2090 } 2245 }
2091} 2246}
2092 2247
2248/* unsolicited event for jack sensing */
2249static void cxt5066_ideapad_event(struct hda_codec *codec, unsigned int res)
2250{
2251 snd_printdd("CXT5066_ideapad: unsol event %x (%x)\n", res, res >> 26);
2252 switch (res >> 26) {
2253 case CONEXANT_HP_EVENT:
2254 cxt5066_hp_automute(codec);
2255 break;
2256 case CONEXANT_MIC_EVENT:
2257 cxt5066_ideapad_automic(codec);
2258 break;
2259 }
2260}
2261
2093static const struct hda_input_mux cxt5066_analog_mic_boost = { 2262static const struct hda_input_mux cxt5066_analog_mic_boost = {
2094 .num_items = 5, 2263 .num_items = 5,
2095 .items = { 2264 .items = {
@@ -2101,6 +2270,23 @@ static const struct hda_input_mux cxt5066_analog_mic_boost = {
2101 }, 2270 },
2102}; 2271};
2103 2272
2273static void cxt5066_set_mic_boost(struct hda_codec *codec)
2274{
2275 struct conexant_spec *spec = codec->spec;
2276 snd_hda_codec_write_cache(codec, 0x17, 0,
2277 AC_VERB_SET_AMP_GAIN_MUTE,
2278 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2279 cxt5066_analog_mic_boost.items[spec->mic_boost].index);
2280 if (spec->ideapad) {
2281 /* adjust the internal mic as well...it is not through 0x17 */
2282 snd_hda_codec_write_cache(codec, 0x23, 0,
2283 AC_VERB_SET_AMP_GAIN_MUTE,
2284 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_INPUT |
2285 cxt5066_analog_mic_boost.
2286 items[spec->mic_boost].index);
2287 }
2288}
2289
2104static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol, 2290static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
2105 struct snd_ctl_elem_info *uinfo) 2291 struct snd_ctl_elem_info *uinfo)
2106{ 2292{
@@ -2111,15 +2297,8 @@ static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
2111 struct snd_ctl_elem_value *ucontrol) 2297 struct snd_ctl_elem_value *ucontrol)
2112{ 2298{
2113 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2299 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2114 int val; 2300 struct conexant_spec *spec = codec->spec;
2115 hda_nid_t nid = kcontrol->private_value & 0xff; 2301 ucontrol->value.enumerated.item[0] = spec->mic_boost;
2116 int inout = (kcontrol->private_value & 0x100) ?
2117 AC_AMP_GET_INPUT : AC_AMP_GET_OUTPUT;
2118
2119 val = snd_hda_codec_read(codec, nid, 0,
2120 AC_VERB_GET_AMP_GAIN_MUTE, inout);
2121
2122 ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN;
2123 return 0; 2302 return 0;
2124} 2303}
2125 2304
@@ -2127,26 +2306,132 @@ static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
2127 struct snd_ctl_elem_value *ucontrol) 2306 struct snd_ctl_elem_value *ucontrol)
2128{ 2307{
2129 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2308 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2309 struct conexant_spec *spec = codec->spec;
2130 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; 2310 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2131 unsigned int idx; 2311 unsigned int idx;
2132 hda_nid_t nid = kcontrol->private_value & 0xff; 2312 idx = ucontrol->value.enumerated.item[0];
2133 int inout = (kcontrol->private_value & 0x100) ? 2313 if (idx >= imux->num_items)
2134 AC_AMP_SET_INPUT : AC_AMP_SET_OUTPUT; 2314 idx = imux->num_items - 1;
2315
2316 spec->mic_boost = idx;
2317 if (!spec->dc_enable)
2318 cxt5066_set_mic_boost(codec);
2319 return 1;
2320}
2321
2322static void cxt5066_enable_dc(struct hda_codec *codec)
2323{
2324 const struct hda_verb enable_dc_mode[] = {
2325 /* disable gain */
2326 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2327
2328 /* switch to DC input */
2329 {0x17, AC_VERB_SET_CONNECT_SEL, 3},
2330 {}
2331 };
2332
2333 /* configure as input source */
2334 snd_hda_sequence_write(codec, enable_dc_mode);
2335 cxt5066_olpc_select_mic(codec); /* also sets configured bias */
2336}
2337
2338static void cxt5066_disable_dc(struct hda_codec *codec)
2339{
2340 /* reconfigure input source */
2341 cxt5066_set_mic_boost(codec);
2342 /* automic also selects the right mic if we're recording */
2343 cxt5066_olpc_automic(codec);
2344}
2345
2346static int cxt5066_olpc_dc_get(struct snd_kcontrol *kcontrol,
2347 struct snd_ctl_elem_value *ucontrol)
2348{
2349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2350 struct conexant_spec *spec = codec->spec;
2351 ucontrol->value.integer.value[0] = spec->dc_enable;
2352 return 0;
2353}
2135 2354
2136 if (!imux->num_items) 2355static int cxt5066_olpc_dc_put(struct snd_kcontrol *kcontrol,
2356 struct snd_ctl_elem_value *ucontrol)
2357{
2358 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2359 struct conexant_spec *spec = codec->spec;
2360 int dc_enable = !!ucontrol->value.integer.value[0];
2361
2362 if (dc_enable == spec->dc_enable)
2137 return 0; 2363 return 0;
2364
2365 spec->dc_enable = dc_enable;
2366 if (dc_enable)
2367 cxt5066_enable_dc(codec);
2368 else
2369 cxt5066_disable_dc(codec);
2370
2371 return 1;
2372}
2373
2374static int cxt5066_olpc_dc_bias_enum_info(struct snd_kcontrol *kcontrol,
2375 struct snd_ctl_elem_info *uinfo)
2376{
2377 return snd_hda_input_mux_info(&cxt5066_olpc_dc_bias, uinfo);
2378}
2379
2380static int cxt5066_olpc_dc_bias_enum_get(struct snd_kcontrol *kcontrol,
2381 struct snd_ctl_elem_value *ucontrol)
2382{
2383 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2384 struct conexant_spec *spec = codec->spec;
2385 ucontrol->value.enumerated.item[0] = spec->dc_input_bias;
2386 return 0;
2387}
2388
2389static int cxt5066_olpc_dc_bias_enum_put(struct snd_kcontrol *kcontrol,
2390 struct snd_ctl_elem_value *ucontrol)
2391{
2392 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2393 struct conexant_spec *spec = codec->spec;
2394 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2395 unsigned int idx;
2396
2138 idx = ucontrol->value.enumerated.item[0]; 2397 idx = ucontrol->value.enumerated.item[0];
2139 if (idx >= imux->num_items) 2398 if (idx >= imux->num_items)
2140 idx = imux->num_items - 1; 2399 idx = imux->num_items - 1;
2141 2400
2142 snd_hda_codec_write_cache(codec, nid, 0, 2401 spec->dc_input_bias = idx;
2143 AC_VERB_SET_AMP_GAIN_MUTE, 2402 if (spec->dc_enable)
2144 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | inout | 2403 cxt5066_set_olpc_dc_bias(codec);
2145 imux->items[idx].index);
2146
2147 return 1; 2404 return 1;
2148} 2405}
2149 2406
2407static void cxt5066_olpc_capture_prepare(struct hda_codec *codec)
2408{
2409 struct conexant_spec *spec = codec->spec;
2410 /* mark as recording and configure the microphone widget so that the
2411 * recording LED comes on. */
2412 spec->recording = 1;
2413 cxt5066_olpc_select_mic(codec);
2414}
2415
2416static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec)
2417{
2418 struct conexant_spec *spec = codec->spec;
2419 const struct hda_verb disable_mics[] = {
2420 /* disable external mic, port B */
2421 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2422
2423 /* disble internal mic, port C */
2424 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2425
2426 /* disable DC capture, port F */
2427 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2428 {},
2429 };
2430
2431 snd_hda_sequence_write(codec, disable_mics);
2432 spec->recording = 0;
2433}
2434
2150static struct hda_input_mux cxt5066_capture_source = { 2435static struct hda_input_mux cxt5066_capture_source = {
2151 .num_items = 4, 2436 .num_items = 4,
2152 .items = { 2437 .items = {
@@ -2187,6 +2472,7 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2187 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 2472 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2188 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 2473 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2189 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, 2474 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2475 .subdevice = HDA_SUBDEV_AMP_FLAG,
2190 .info = snd_hda_mixer_amp_volume_info, 2476 .info = snd_hda_mixer_amp_volume_info,
2191 .get = snd_hda_mixer_amp_volume_get, 2477 .get = snd_hda_mixer_amp_volume_get,
2192 .put = snd_hda_mixer_amp_volume_put, 2478 .put = snd_hda_mixer_amp_volume_put,
@@ -2198,6 +2484,24 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2198 {} 2484 {}
2199}; 2485};
2200 2486
2487static struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
2488 {
2489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2490 .name = "DC Mode Enable Switch",
2491 .info = snd_ctl_boolean_mono_info,
2492 .get = cxt5066_olpc_dc_get,
2493 .put = cxt5066_olpc_dc_put,
2494 },
2495 {
2496 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2497 .name = "DC Input Bias Enum",
2498 .info = cxt5066_olpc_dc_bias_enum_info,
2499 .get = cxt5066_olpc_dc_bias_enum_get,
2500 .put = cxt5066_olpc_dc_bias_enum_put,
2501 },
2502 {}
2503};
2504
2201static struct snd_kcontrol_new cxt5066_mixers[] = { 2505static struct snd_kcontrol_new cxt5066_mixers[] = {
2202 { 2506 {
2203 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2507 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -2210,11 +2514,10 @@ static struct snd_kcontrol_new cxt5066_mixers[] = {
2210 2514
2211 { 2515 {
2212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2516 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2213 .name = "Ext Mic Boost Capture Enum", 2517 .name = "Analog Mic Boost Capture Enum",
2214 .info = cxt5066_mic_boost_mux_enum_info, 2518 .info = cxt5066_mic_boost_mux_enum_info,
2215 .get = cxt5066_mic_boost_mux_enum_get, 2519 .get = cxt5066_mic_boost_mux_enum_get,
2216 .put = cxt5066_mic_boost_mux_enum_put, 2520 .put = cxt5066_mic_boost_mux_enum_put,
2217 .private_value = 0x17,
2218 }, 2521 },
2219 2522
2220 HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others), 2523 HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others),
@@ -2296,10 +2599,10 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = {
2296 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2599 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2297 2600
2298 /* Port B: external microphone */ 2601 /* Port B: external microphone */
2299 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, CXT5066_OLPC_EXT_MIC_BIAS}, 2602 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2300 2603
2301 /* Port C: internal microphone */ 2604 /* Port C: internal microphone */
2302 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2605 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2303 2606
2304 /* Port D: unused */ 2607 /* Port D: unused */
2305 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2608 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
@@ -2308,7 +2611,7 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = {
2308 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2611 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2309 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 2612 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2310 2613
2311 /* Port F: unused */ 2614 /* Port F: external DC input through microphone port */
2312 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2615 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2313 2616
2314 /* Port G: internal speakers */ 2617 /* Port G: internal speakers */
@@ -2412,6 +2715,56 @@ static struct hda_verb cxt5066_init_verbs_vostro[] = {
2412 { } /* end */ 2715 { } /* end */
2413}; 2716};
2414 2717
2718static struct hda_verb cxt5066_init_verbs_ideapad[] = {
2719 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2720 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2721 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2722 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2723
2724 /* Speakers */
2725 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2726 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2727
2728 /* HP, Amp */
2729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2730 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2731
2732 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2733 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2734
2735 /* DAC1 */
2736 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2737
2738 /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2739 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2740 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2741 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2742 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2743 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2744 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, /* default to internal mic */
2745
2746 /* Audio input selector */
2747 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2748 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, /* route ext mic */
2749
2750 /* SPDIF route: PCM */
2751 {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2752 {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2753
2754 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2755 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2756
2757 /* internal microphone */
2758 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */
2759
2760 /* EAPD */
2761 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2762
2763 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2764 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2765 { } /* end */
2766};
2767
2415static struct hda_verb cxt5066_init_verbs_portd_lo[] = { 2768static struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2416 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2769 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2417 { } /* end */ 2770 { } /* end */
@@ -2428,8 +2781,24 @@ static int cxt5066_init(struct hda_codec *codec)
2428 cxt5066_hp_automute(codec); 2781 cxt5066_hp_automute(codec);
2429 if (spec->dell_vostro) 2782 if (spec->dell_vostro)
2430 cxt5066_vostro_automic(codec); 2783 cxt5066_vostro_automic(codec);
2431 else 2784 else if (spec->ideapad)
2432 cxt5066_automic(codec); 2785 cxt5066_ideapad_automic(codec);
2786 }
2787 cxt5066_set_mic_boost(codec);
2788 return 0;
2789}
2790
2791static int cxt5066_olpc_init(struct hda_codec *codec)
2792{
2793 struct conexant_spec *spec = codec->spec;
2794 snd_printdd("CXT5066: init\n");
2795 conexant_init(codec);
2796 cxt5066_hp_automute(codec);
2797 if (!spec->dc_enable) {
2798 cxt5066_set_mic_boost(codec);
2799 cxt5066_olpc_automic(codec);
2800 } else {
2801 cxt5066_enable_dc(codec);
2433 } 2802 }
2434 return 0; 2803 return 0;
2435} 2804}
@@ -2439,6 +2808,7 @@ enum {
2439 CXT5066_DELL_LAPTOP, /* Dell Laptop */ 2808 CXT5066_DELL_LAPTOP, /* Dell Laptop */
2440 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ 2809 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */
2441 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ 2810 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */
2811 CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */
2442 CXT5066_MODELS 2812 CXT5066_MODELS
2443}; 2813};
2444 2814
@@ -2446,7 +2816,8 @@ static const char *cxt5066_models[CXT5066_MODELS] = {
2446 [CXT5066_LAPTOP] = "laptop", 2816 [CXT5066_LAPTOP] = "laptop",
2447 [CXT5066_DELL_LAPTOP] = "dell-laptop", 2817 [CXT5066_DELL_LAPTOP] = "dell-laptop",
2448 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", 2818 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5",
2449 [CXT5066_DELL_VOSTO] = "dell-vostro" 2819 [CXT5066_DELL_VOSTO] = "dell-vostro",
2820 [CXT5066_IDEAPAD] = "ideapad",
2450}; 2821};
2451 2822
2452static struct snd_pci_quirk cxt5066_cfg_tbl[] = { 2823static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
@@ -2456,6 +2827,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2456 CXT5066_DELL_LAPTOP), 2827 CXT5066_DELL_LAPTOP),
2457 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), 2828 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
2458 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), 2829 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO),
2830 SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD),
2459 {} 2831 {}
2460}; 2832};
2461 2833
@@ -2470,7 +2842,7 @@ static int patch_cxt5066(struct hda_codec *codec)
2470 codec->spec = spec; 2842 codec->spec = spec;
2471 2843
2472 codec->patch_ops = conexant_patch_ops; 2844 codec->patch_ops = conexant_patch_ops;
2473 codec->patch_ops.init = cxt5066_init; 2845 codec->patch_ops.init = conexant_init;
2474 2846
2475 spec->dell_automute = 0; 2847 spec->dell_automute = 0;
2476 spec->multiout.max_channels = 2; 2848 spec->multiout.max_channels = 2;
@@ -2483,7 +2855,6 @@ static int patch_cxt5066(struct hda_codec *codec)
2483 spec->input_mux = &cxt5066_capture_source; 2855 spec->input_mux = &cxt5066_capture_source;
2484 2856
2485 spec->port_d_mode = PIN_HP; 2857 spec->port_d_mode = PIN_HP;
2486 spec->ext_mic_bias = PIN_VREF80;
2487 2858
2488 spec->num_init_verbs = 1; 2859 spec->num_init_verbs = 1;
2489 spec->init_verbs[0] = cxt5066_init_verbs; 2860 spec->init_verbs[0] = cxt5066_init_verbs;
@@ -2510,20 +2881,28 @@ static int patch_cxt5066(struct hda_codec *codec)
2510 spec->dell_automute = 1; 2881 spec->dell_automute = 1;
2511 break; 2882 break;
2512 case CXT5066_OLPC_XO_1_5: 2883 case CXT5066_OLPC_XO_1_5:
2513 codec->patch_ops.unsol_event = cxt5066_unsol_event; 2884 codec->patch_ops.init = cxt5066_olpc_init;
2885 codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event;
2514 spec->init_verbs[0] = cxt5066_init_verbs_olpc; 2886 spec->init_verbs[0] = cxt5066_init_verbs_olpc;
2515 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; 2887 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
2888 spec->mixers[spec->num_mixers++] = cxt5066_mixer_olpc_dc;
2516 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 2889 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2517 spec->port_d_mode = 0; 2890 spec->port_d_mode = 0;
2518 spec->ext_mic_bias = CXT5066_OLPC_EXT_MIC_BIAS; 2891 spec->mic_boost = 3; /* default 30dB gain */
2519 2892
2520 /* no S/PDIF out */ 2893 /* no S/PDIF out */
2521 spec->multiout.dig_out_nid = 0; 2894 spec->multiout.dig_out_nid = 0;
2522 2895
2523 /* input source automatically selected */ 2896 /* input source automatically selected */
2524 spec->input_mux = NULL; 2897 spec->input_mux = NULL;
2898
2899 /* our capture hooks which allow us to turn on the microphone LED
2900 * at the right time */
2901 spec->capture_prepare = cxt5066_olpc_capture_prepare;
2902 spec->capture_cleanup = cxt5066_olpc_capture_cleanup;
2525 break; 2903 break;
2526 case CXT5066_DELL_VOSTO: 2904 case CXT5066_DELL_VOSTO:
2905 codec->patch_ops.init = cxt5066_init;
2527 codec->patch_ops.unsol_event = cxt5066_vostro_event; 2906 codec->patch_ops.unsol_event = cxt5066_vostro_event;
2528 spec->init_verbs[0] = cxt5066_init_verbs_vostro; 2907 spec->init_verbs[0] = cxt5066_init_verbs_vostro;
2529 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; 2908 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
@@ -2531,6 +2910,7 @@ static int patch_cxt5066(struct hda_codec *codec)
2531 spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers; 2910 spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers;
2532 spec->port_d_mode = 0; 2911 spec->port_d_mode = 0;
2533 spec->dell_vostro = 1; 2912 spec->dell_vostro = 1;
2913 spec->mic_boost = 3; /* default 30dB gain */
2534 snd_hda_attach_beep_device(codec, 0x13); 2914 snd_hda_attach_beep_device(codec, 0x13);
2535 2915
2536 /* no S/PDIF out */ 2916 /* no S/PDIF out */
@@ -2539,6 +2919,22 @@ static int patch_cxt5066(struct hda_codec *codec)
2539 /* input source automatically selected */ 2919 /* input source automatically selected */
2540 spec->input_mux = NULL; 2920 spec->input_mux = NULL;
2541 break; 2921 break;
2922 case CXT5066_IDEAPAD:
2923 codec->patch_ops.init = cxt5066_init;
2924 codec->patch_ops.unsol_event = cxt5066_ideapad_event;
2925 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
2926 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2927 spec->init_verbs[0] = cxt5066_init_verbs_ideapad;
2928 spec->port_d_mode = 0;
2929 spec->ideapad = 1;
2930 spec->mic_boost = 2; /* default 20dB gain */
2931
2932 /* no S/PDIF out */
2933 spec->multiout.dig_out_nid = 0;
2934
2935 /* input source automatically selected */
2936 spec->input_mux = NULL;
2937 break;
2542 } 2938 }
2543 2939
2544 return 0; 2940 return 0;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index da34095c707f..e8cbe216e912 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -131,8 +131,10 @@ enum {
131enum { 131enum {
132 ALC269_BASIC, 132 ALC269_BASIC,
133 ALC269_QUANTA_FL1, 133 ALC269_QUANTA_FL1,
134 ALC269_ASUS_AMIC, 134 ALC269_AMIC,
135 ALC269_ASUS_DMIC, 135 ALC269_DMIC,
136 ALC269VB_AMIC,
137 ALC269VB_DMIC,
136 ALC269_FUJITSU, 138 ALC269_FUJITSU,
137 ALC269_LIFEBOOK, 139 ALC269_LIFEBOOK,
138 ALC269_AUTO, 140 ALC269_AUTO,
@@ -207,8 +209,10 @@ enum {
207 ALC882_ASUS_A7J, 209 ALC882_ASUS_A7J,
208 ALC882_ASUS_A7M, 210 ALC882_ASUS_A7M,
209 ALC885_MACPRO, 211 ALC885_MACPRO,
212 ALC885_MBA21,
210 ALC885_MBP3, 213 ALC885_MBP3,
211 ALC885_MB5, 214 ALC885_MB5,
215 ALC885_MACMINI3,
212 ALC885_IMAC24, 216 ALC885_IMAC24,
213 ALC885_IMAC91, 217 ALC885_IMAC91,
214 ALC883_3ST_2ch_DIG, 218 ALC883_3ST_2ch_DIG,
@@ -338,7 +342,7 @@ struct alc_spec {
338 void (*init_hook)(struct hda_codec *codec); 342 void (*init_hook)(struct hda_codec *codec);
339 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 343 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
340#ifdef CONFIG_SND_HDA_POWER_SAVE 344#ifdef CONFIG_SND_HDA_POWER_SAVE
341 void (*power_hook)(struct hda_codec *codec, int power); 345 void (*power_hook)(struct hda_codec *codec);
342#endif 346#endif
343 347
344 /* for pin sensing */ 348 /* for pin sensing */
@@ -391,7 +395,7 @@ struct alc_config_preset {
391 void (*init_hook)(struct hda_codec *); 395 void (*init_hook)(struct hda_codec *);
392#ifdef CONFIG_SND_HDA_POWER_SAVE 396#ifdef CONFIG_SND_HDA_POWER_SAVE
393 struct hda_amp_list *loopbacks; 397 struct hda_amp_list *loopbacks;
394 void (*power_hook)(struct hda_codec *codec, int power); 398 void (*power_hook)(struct hda_codec *codec);
395#endif 399#endif
396}; 400};
397 401
@@ -633,6 +637,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
633 637
634#define ALC_PIN_MODE(xname, nid, dir) \ 638#define ALC_PIN_MODE(xname, nid, dir) \
635 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 639 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
640 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
636 .info = alc_pin_mode_info, \ 641 .info = alc_pin_mode_info, \
637 .get = alc_pin_mode_get, \ 642 .get = alc_pin_mode_get, \
638 .put = alc_pin_mode_put, \ 643 .put = alc_pin_mode_put, \
@@ -684,6 +689,7 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
684} 689}
685#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 690#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
686 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 691 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
692 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
687 .info = alc_gpio_data_info, \ 693 .info = alc_gpio_data_info, \
688 .get = alc_gpio_data_get, \ 694 .get = alc_gpio_data_get, \
689 .put = alc_gpio_data_put, \ 695 .put = alc_gpio_data_put, \
@@ -738,6 +744,7 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
738} 744}
739#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 745#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
740 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 746 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
747 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
741 .info = alc_spdif_ctrl_info, \ 748 .info = alc_spdif_ctrl_info, \
742 .get = alc_spdif_ctrl_get, \ 749 .get = alc_spdif_ctrl_get, \
743 .put = alc_spdif_ctrl_put, \ 750 .put = alc_spdif_ctrl_put, \
@@ -791,6 +798,7 @@ static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
791 798
792#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 799#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
793 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 800 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
801 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
794 .info = alc_eapd_ctrl_info, \ 802 .info = alc_eapd_ctrl_info, \
795 .get = alc_eapd_ctrl_get, \ 803 .get = alc_eapd_ctrl_get, \
796 .put = alc_eapd_ctrl_put, \ 804 .put = alc_eapd_ctrl_put, \
@@ -837,27 +845,6 @@ static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
837 spec->init_verbs[spec->num_init_verbs++] = verb; 845 spec->init_verbs[spec->num_init_verbs++] = verb;
838} 846}
839 847
840#ifdef CONFIG_PROC_FS
841/*
842 * hook for proc
843 */
844static void print_realtek_coef(struct snd_info_buffer *buffer,
845 struct hda_codec *codec, hda_nid_t nid)
846{
847 int coeff;
848
849 if (nid != 0x20)
850 return;
851 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
852 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
853 coeff = snd_hda_codec_read(codec, nid, 0,
854 AC_VERB_GET_COEF_INDEX, 0);
855 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
856}
857#else
858#define print_realtek_coef NULL
859#endif
860
861/* 848/*
862 * set up from the preset table 849 * set up from the preset table
863 */ 850 */
@@ -1162,6 +1149,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1162 case 0x10ec0888: 1149 case 0x10ec0888:
1163 alc888_coef_init(codec); 1150 alc888_coef_init(codec);
1164 break; 1151 break;
1152#if 0 /* XXX: This may cause the silent output on speaker on some machines */
1165 case 0x10ec0267: 1153 case 0x10ec0267:
1166 case 0x10ec0268: 1154 case 0x10ec0268:
1167 snd_hda_codec_write(codec, 0x20, 0, 1155 snd_hda_codec_write(codec, 0x20, 0,
@@ -1174,6 +1162,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1174 AC_VERB_SET_PROC_COEF, 1162 AC_VERB_SET_PROC_COEF,
1175 tmp | 0x3000); 1163 tmp | 0x3000);
1176 break; 1164 break;
1165#endif /* XXX */
1177 } 1166 }
1178 break; 1167 break;
1179 } 1168 }
@@ -1265,7 +1254,7 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1265 */ 1254 */
1266static int alc_subsystem_id(struct hda_codec *codec, 1255static int alc_subsystem_id(struct hda_codec *codec,
1267 hda_nid_t porta, hda_nid_t porte, 1256 hda_nid_t porta, hda_nid_t porte,
1268 hda_nid_t portd) 1257 hda_nid_t portd, hda_nid_t porti)
1269{ 1258{
1270 unsigned int ass, tmp, i; 1259 unsigned int ass, tmp, i;
1271 unsigned nid; 1260 unsigned nid;
@@ -1291,7 +1280,7 @@ static int alc_subsystem_id(struct hda_codec *codec,
1291 snd_printd("realtek: No valid SSID, " 1280 snd_printd("realtek: No valid SSID, "
1292 "checking pincfg 0x%08x for NID 0x%x\n", 1281 "checking pincfg 0x%08x for NID 0x%x\n",
1293 ass, nid); 1282 ass, nid);
1294 if (!(ass & 1) && !(ass & 0x100000)) 1283 if (!(ass & 1))
1295 return 0; 1284 return 0;
1296 if ((ass >> 30) != 1) /* no physical connection */ 1285 if ((ass >> 30) != 1) /* no physical connection */
1297 return 0; 1286 return 0;
@@ -1351,6 +1340,8 @@ do_sku:
1351 nid = porte; 1340 nid = porte;
1352 else if (tmp == 2) 1341 else if (tmp == 2)
1353 nid = portd; 1342 nid = portd;
1343 else if (tmp == 3)
1344 nid = porti;
1354 else 1345 else
1355 return 1; 1346 return 1;
1356 for (i = 0; i < spec->autocfg.line_outs; i++) 1347 for (i = 0; i < spec->autocfg.line_outs; i++)
@@ -1365,9 +1356,10 @@ do_sku:
1365} 1356}
1366 1357
1367static void alc_ssid_check(struct hda_codec *codec, 1358static void alc_ssid_check(struct hda_codec *codec,
1368 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd) 1359 hda_nid_t porta, hda_nid_t porte,
1360 hda_nid_t portd, hda_nid_t porti)
1369{ 1361{
1370 if (!alc_subsystem_id(codec, porta, porte, portd)) { 1362 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1371 struct alc_spec *spec = codec->spec; 1363 struct alc_spec *spec = codec->spec;
1372 snd_printd("realtek: " 1364 snd_printd("realtek: "
1373 "Enable default setup for auto mode as fallback\n"); 1365 "Enable default setup for auto mode as fallback\n");
@@ -1840,14 +1832,6 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
1840 spec->autocfg.speaker_pins[2] = 0x1b; 1832 spec->autocfg.speaker_pins[2] = 0x1b;
1841} 1833}
1842 1834
1843#ifdef CONFIG_SND_HDA_POWER_SAVE
1844static void alc889_power_eapd(struct hda_codec *codec, int power)
1845{
1846 set_eapd(codec, 0x14, power);
1847 set_eapd(codec, 0x15, power);
1848}
1849#endif
1850
1851/* 1835/*
1852 * ALC880 3-stack model 1836 * ALC880 3-stack model
1853 * 1837 *
@@ -2450,6 +2434,15 @@ static const char *alc_slave_sws[] = {
2450 * build control elements 2434 * build control elements
2451 */ 2435 */
2452 2436
2437#define NID_MAPPING (-1)
2438
2439#define SUBDEV_SPEAKER_ (0 << 6)
2440#define SUBDEV_HP_ (1 << 6)
2441#define SUBDEV_LINE_ (2 << 6)
2442#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2443#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2444#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2445
2453static void alc_free_kctls(struct hda_codec *codec); 2446static void alc_free_kctls(struct hda_codec *codec);
2454 2447
2455#ifdef CONFIG_SND_HDA_INPUT_BEEP 2448#ifdef CONFIG_SND_HDA_INPUT_BEEP
@@ -2464,8 +2457,11 @@ static struct snd_kcontrol_new alc_beep_mixer[] = {
2464static int alc_build_controls(struct hda_codec *codec) 2457static int alc_build_controls(struct hda_codec *codec)
2465{ 2458{
2466 struct alc_spec *spec = codec->spec; 2459 struct alc_spec *spec = codec->spec;
2467 int err; 2460 struct snd_kcontrol *kctl;
2468 int i; 2461 struct snd_kcontrol_new *knew;
2462 int i, j, err;
2463 unsigned int u;
2464 hda_nid_t nid;
2469 2465
2470 for (i = 0; i < spec->num_mixers; i++) { 2466 for (i = 0; i < spec->num_mixers; i++) {
2471 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 2467 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
@@ -2506,8 +2502,7 @@ static int alc_build_controls(struct hda_codec *codec)
2506 if (!kctl) 2502 if (!kctl)
2507 return -ENOMEM; 2503 return -ENOMEM;
2508 kctl->private_value = spec->beep_amp; 2504 kctl->private_value = spec->beep_amp;
2509 err = snd_hda_ctl_add(codec, 2505 err = snd_hda_ctl_add(codec, 0, kctl);
2510 get_amp_nid_(spec->beep_amp), kctl);
2511 if (err < 0) 2506 if (err < 0)
2512 return err; 2507 return err;
2513 } 2508 }
@@ -2534,6 +2529,75 @@ static int alc_build_controls(struct hda_codec *codec)
2534 } 2529 }
2535 2530
2536 alc_free_kctls(codec); /* no longer needed */ 2531 alc_free_kctls(codec); /* no longer needed */
2532
2533 /* assign Capture Source enums to NID */
2534 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2535 if (!kctl)
2536 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2537 for (i = 0; kctl && i < kctl->count; i++) {
2538 hda_nid_t *nids = spec->capsrc_nids;
2539 if (!nids)
2540 nids = spec->adc_nids;
2541 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2542 if (err < 0)
2543 return err;
2544 }
2545 if (spec->cap_mixer) {
2546 const char *kname = kctl ? kctl->id.name : NULL;
2547 for (knew = spec->cap_mixer; knew->name; knew++) {
2548 if (kname && strcmp(knew->name, kname) == 0)
2549 continue;
2550 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2551 for (i = 0; kctl && i < kctl->count; i++) {
2552 err = snd_hda_add_nid(codec, kctl, i,
2553 spec->adc_nids[i]);
2554 if (err < 0)
2555 return err;
2556 }
2557 }
2558 }
2559
2560 /* other nid->control mapping */
2561 for (i = 0; i < spec->num_mixers; i++) {
2562 for (knew = spec->mixers[i]; knew->name; knew++) {
2563 if (knew->iface != NID_MAPPING)
2564 continue;
2565 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2566 if (kctl == NULL)
2567 continue;
2568 u = knew->subdevice;
2569 for (j = 0; j < 4; j++, u >>= 8) {
2570 nid = u & 0x3f;
2571 if (nid == 0)
2572 continue;
2573 switch (u & 0xc0) {
2574 case SUBDEV_SPEAKER_:
2575 nid = spec->autocfg.speaker_pins[nid];
2576 break;
2577 case SUBDEV_LINE_:
2578 nid = spec->autocfg.line_out_pins[nid];
2579 break;
2580 case SUBDEV_HP_:
2581 nid = spec->autocfg.hp_pins[nid];
2582 break;
2583 default:
2584 continue;
2585 }
2586 err = snd_hda_add_nid(codec, kctl, 0, nid);
2587 if (err < 0)
2588 return err;
2589 }
2590 u = knew->private_value;
2591 for (j = 0; j < 4; j++, u >>= 8) {
2592 nid = u & 0xff;
2593 if (nid == 0)
2594 continue;
2595 err = snd_hda_add_nid(codec, kctl, 0, nid);
2596 if (err < 0)
2597 return err;
2598 }
2599 }
2600 }
2537 return 0; 2601 return 0;
2538} 2602}
2539 2603
@@ -3616,6 +3680,11 @@ static int alc_build_pcms(struct hda_codec *codec)
3616 return 0; 3680 return 0;
3617} 3681}
3618 3682
3683static inline void alc_shutup(struct hda_codec *codec)
3684{
3685 snd_hda_shutup_pins(codec);
3686}
3687
3619static void alc_free_kctls(struct hda_codec *codec) 3688static void alc_free_kctls(struct hda_codec *codec)
3620{ 3689{
3621 struct alc_spec *spec = codec->spec; 3690 struct alc_spec *spec = codec->spec;
@@ -3636,17 +3705,44 @@ static void alc_free(struct hda_codec *codec)
3636 if (!spec) 3705 if (!spec)
3637 return; 3706 return;
3638 3707
3708 alc_shutup(codec);
3639 alc_free_kctls(codec); 3709 alc_free_kctls(codec);
3640 kfree(spec); 3710 kfree(spec);
3641 snd_hda_detach_beep_device(codec); 3711 snd_hda_detach_beep_device(codec);
3642} 3712}
3643 3713
3644#ifdef CONFIG_SND_HDA_POWER_SAVE 3714#ifdef CONFIG_SND_HDA_POWER_SAVE
3715static void alc_power_eapd(struct hda_codec *codec)
3716{
3717 /* We currently only handle front, HP */
3718 switch (codec->vendor_id) {
3719 case 0x10ec0260:
3720 set_eapd(codec, 0x0f, 0);
3721 set_eapd(codec, 0x10, 0);
3722 break;
3723 case 0x10ec0262:
3724 case 0x10ec0267:
3725 case 0x10ec0268:
3726 case 0x10ec0269:
3727 case 0x10ec0270:
3728 case 0x10ec0272:
3729 case 0x10ec0660:
3730 case 0x10ec0662:
3731 case 0x10ec0663:
3732 case 0x10ec0862:
3733 case 0x10ec0889:
3734 set_eapd(codec, 0x14, 0);
3735 set_eapd(codec, 0x15, 0);
3736 break;
3737 }
3738}
3739
3645static int alc_suspend(struct hda_codec *codec, pm_message_t state) 3740static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3646{ 3741{
3647 struct alc_spec *spec = codec->spec; 3742 struct alc_spec *spec = codec->spec;
3743 alc_shutup(codec);
3648 if (spec && spec->power_hook) 3744 if (spec && spec->power_hook)
3649 spec->power_hook(codec, 0); 3745 spec->power_hook(codec);
3650 return 0; 3746 return 0;
3651} 3747}
3652#endif 3748#endif
@@ -3654,16 +3750,9 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3654#ifdef SND_HDA_NEEDS_RESUME 3750#ifdef SND_HDA_NEEDS_RESUME
3655static int alc_resume(struct hda_codec *codec) 3751static int alc_resume(struct hda_codec *codec)
3656{ 3752{
3657#ifdef CONFIG_SND_HDA_POWER_SAVE
3658 struct alc_spec *spec = codec->spec;
3659#endif
3660 codec->patch_ops.init(codec); 3753 codec->patch_ops.init(codec);
3661 snd_hda_codec_resume_amp(codec); 3754 snd_hda_codec_resume_amp(codec);
3662 snd_hda_codec_resume_cache(codec); 3755 snd_hda_codec_resume_cache(codec);
3663#ifdef CONFIG_SND_HDA_POWER_SAVE
3664 if (spec && spec->power_hook)
3665 spec->power_hook(codec, 1);
3666#endif
3667 return 0; 3756 return 0;
3668} 3757}
3669#endif 3758#endif
@@ -3683,6 +3772,7 @@ static struct hda_codec_ops alc_patch_ops = {
3683 .suspend = alc_suspend, 3772 .suspend = alc_suspend,
3684 .check_power_status = alc_check_power_status, 3773 .check_power_status = alc_check_power_status,
3685#endif 3774#endif
3775 .reboot_notify = alc_shutup,
3686}; 3776};
3687 3777
3688 3778
@@ -3839,6 +3929,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3839#define PIN_CTL_TEST(xname,nid) { \ 3929#define PIN_CTL_TEST(xname,nid) { \
3840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3930 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3841 .name = xname, \ 3931 .name = xname, \
3932 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3842 .info = alc_test_pin_ctl_info, \ 3933 .info = alc_test_pin_ctl_info, \
3843 .get = alc_test_pin_ctl_get, \ 3934 .get = alc_test_pin_ctl_get, \
3844 .put = alc_test_pin_ctl_put, \ 3935 .put = alc_test_pin_ctl_put, \
@@ -3848,6 +3939,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3848#define PIN_SRC_TEST(xname,nid) { \ 3939#define PIN_SRC_TEST(xname,nid) { \
3849 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3940 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3850 .name = xname, \ 3941 .name = xname, \
3942 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3851 .info = alc_test_pin_src_info, \ 3943 .info = alc_test_pin_src_info, \
3852 .get = alc_test_pin_src_get, \ 3944 .get = alc_test_pin_src_get, \
3853 .put = alc_test_pin_src_put, \ 3945 .put = alc_test_pin_src_put, \
@@ -4387,7 +4479,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
4387 if (!knew->name) 4479 if (!knew->name)
4388 return -ENOMEM; 4480 return -ENOMEM;
4389 if (get_amp_nid_(val)) 4481 if (get_amp_nid_(val))
4390 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 4482 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
4391 knew->private_value = val; 4483 knew->private_value = val;
4392 return 0; 4484 return 0;
4393} 4485}
@@ -4770,7 +4862,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
4770 spec->num_mux_defs = 1; 4862 spec->num_mux_defs = 1;
4771 spec->input_mux = &spec->private_imux[0]; 4863 spec->input_mux = &spec->private_imux[0];
4772 4864
4773 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 4865 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4774 4866
4775 return 1; 4867 return 1;
4776} 4868}
@@ -4974,7 +5066,6 @@ static int patch_alc880(struct hda_codec *codec)
4974 if (!spec->loopback.amplist) 5066 if (!spec->loopback.amplist)
4975 spec->loopback.amplist = alc880_loopbacks; 5067 spec->loopback.amplist = alc880_loopbacks;
4976#endif 5068#endif
4977 codec->proc_widget_hook = print_realtek_coef;
4978 5069
4979 return 0; 5070 return 0;
4980} 5071}
@@ -5182,6 +5273,7 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5182 { 5273 {
5183 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5274 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5184 .name = "Master Playback Switch", 5275 .name = "Master Playback Switch",
5276 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5185 .info = snd_ctl_boolean_mono_info, 5277 .info = snd_ctl_boolean_mono_info,
5186 .get = alc260_hp_master_sw_get, 5278 .get = alc260_hp_master_sw_get,
5187 .put = alc260_hp_master_sw_put, 5279 .put = alc260_hp_master_sw_put,
@@ -5220,6 +5312,7 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5220 { 5312 {
5221 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5313 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5222 .name = "Master Playback Switch", 5314 .name = "Master Playback Switch",
5315 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5223 .info = snd_ctl_boolean_mono_info, 5316 .info = snd_ctl_boolean_mono_info,
5224 .get = alc260_hp_master_sw_get, 5317 .get = alc260_hp_master_sw_get,
5225 .put = alc260_hp_master_sw_put, 5318 .put = alc260_hp_master_sw_put,
@@ -6303,7 +6396,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
6303 spec->num_mux_defs = 1; 6396 spec->num_mux_defs = 1;
6304 spec->input_mux = &spec->private_imux[0]; 6397 spec->input_mux = &spec->private_imux[0];
6305 6398
6306 alc_ssid_check(codec, 0x10, 0x15, 0x0f); 6399 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
6307 6400
6308 return 1; 6401 return 1;
6309} 6402}
@@ -6582,7 +6675,6 @@ static int patch_alc260(struct hda_codec *codec)
6582 if (!spec->loopback.amplist) 6675 if (!spec->loopback.amplist)
6583 spec->loopback.amplist = alc260_loopbacks; 6676 spec->loopback.amplist = alc260_loopbacks;
6584#endif 6677#endif
6585 codec->proc_widget_hook = print_realtek_coef;
6586 6678
6587 return 0; 6679 return 0;
6588} 6680}
@@ -6664,6 +6756,14 @@ static struct hda_input_mux mb5_capture_source = {
6664 }, 6756 },
6665}; 6757};
6666 6758
6759static struct hda_input_mux macmini3_capture_source = {
6760 .num_items = 2,
6761 .items = {
6762 { "Line", 0x2 },
6763 { "CD", 0x4 },
6764 },
6765};
6766
6667static struct hda_input_mux alc883_3stack_6ch_intel = { 6767static struct hda_input_mux alc883_3stack_6ch_intel = {
6668 .num_items = 4, 6768 .num_items = 4,
6669 .items = { 6769 .items = {
@@ -6852,6 +6952,13 @@ static struct hda_channel_mode alc882_sixstack_modes[2] = {
6852 { 8, alc882_sixstack_ch8_init }, 6952 { 8, alc882_sixstack_ch8_init },
6853}; 6953};
6854 6954
6955
6956/* Macbook Air 2,1 */
6957
6958static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
6959 { 2, NULL },
6960};
6961
6855/* 6962/*
6856 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic 6963 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
6857 */ 6964 */
@@ -6912,6 +7019,7 @@ static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6912 { 6, alc885_mb5_ch6_init }, 7019 { 6, alc885_mb5_ch6_init },
6913}; 7020};
6914 7021
7022#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
6915 7023
6916/* 7024/*
6917 * 2ch mode 7025 * 2ch mode
@@ -7123,6 +7231,15 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
7123 { } /* end */ 7231 { } /* end */
7124}; 7232};
7125 7233
7234/* Macbook Air 2,1 same control for HP and internal Speaker */
7235
7236static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7237 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7238 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7239 { }
7240};
7241
7242
7126static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 7243static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7127 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7244 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7128 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 7245 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
@@ -7156,6 +7273,21 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7156 { } /* end */ 7273 { } /* end */
7157}; 7274};
7158 7275
7276static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7277 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7278 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7279 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7280 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7281 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7282 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7283 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7284 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7285 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7286 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7287 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7288 { } /* end */
7289};
7290
7159static struct snd_kcontrol_new alc885_imac91_mixer[] = { 7291static struct snd_kcontrol_new alc885_imac91_mixer[] = {
7160 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7292 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7161 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT), 7293 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
@@ -7247,29 +7379,18 @@ static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7247 7379
7248static struct hda_verb alc882_base_init_verbs[] = { 7380static struct hda_verb alc882_base_init_verbs[] = {
7249 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7381 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7251 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7382 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7252 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7383 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7253 /* Rear mixer */ 7384 /* Rear mixer */
7254 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7255 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7385 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7256 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7386 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7257 /* CLFE mixer */ 7387 /* CLFE mixer */
7258 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7259 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7388 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7260 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7389 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7261 /* Side mixer */ 7390 /* Side mixer */
7262 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7263 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7391 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7264 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7392 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7265 7393
7266 /* mute analog input loopbacks */
7267 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7268 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7269 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7270 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7271 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7272
7273 /* Front Pin: output 0 (0x0c) */ 7394 /* Front Pin: output 0 (0x0c) */
7274 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7395 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7275 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7396 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -7306,14 +7427,8 @@ static struct hda_verb alc882_base_init_verbs[] = {
7306 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7427 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7307 /* Input mixer2 */ 7428 /* Input mixer2 */
7308 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7429 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7309 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7310 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7311 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7312 /* Input mixer3 */ 7430 /* Input mixer3 */
7313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7431 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7315 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7316 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7317 /* ADC2: mute amp left and right */ 7432 /* ADC2: mute amp left and right */
7318 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7433 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7319 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7434 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -7357,26 +7472,17 @@ static struct hda_verb alc_hp15_unsol_verbs[] = {
7357 7472
7358static struct hda_verb alc885_init_verbs[] = { 7473static struct hda_verb alc885_init_verbs[] = {
7359 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7474 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7475 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7361 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7476 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7362 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7363 /* Rear mixer */ 7477 /* Rear mixer */
7364 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7478 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7365 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7479 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7366 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7367 /* CLFE mixer */ 7480 /* CLFE mixer */
7368 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7481 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7369 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7482 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7370 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7371 /* Side mixer */ 7483 /* Side mixer */
7372 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7484 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7373 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7485 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7374 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7375
7376 /* mute analog input loopbacks */
7377 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7378 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7379 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7380 7486
7381 /* Front HP Pin: output 0 (0x0c) */ 7487 /* Front HP Pin: output 0 (0x0c) */
7382 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7488 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -7410,17 +7516,11 @@ static struct hda_verb alc885_init_verbs[] = {
7410 7516
7411 /* Mixer elements: 0x18, , 0x1a, 0x1b */ 7517 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7412 /* Input mixer1 */ 7518 /* Input mixer1 */
7413 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 7519 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7414 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7415 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7416 /* Input mixer2 */ 7520 /* Input mixer2 */
7417 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7418 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7419 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7420 /* Input mixer3 */ 7522 /* Input mixer3 */
7421 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 7523 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7422 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7423 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7424 /* ADC2: mute amp left and right */ 7524 /* ADC2: mute amp left and right */
7425 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7525 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7426 /* ADC3: mute amp left and right */ 7526 /* ADC3: mute amp left and right */
@@ -7562,6 +7662,76 @@ static struct hda_verb alc885_mb5_init_verbs[] = {
7562 { } 7662 { }
7563}; 7663};
7564 7664
7665/* Macmini 3,1 */
7666static struct hda_verb alc885_macmini3_init_verbs[] = {
7667 /* DACs */
7668 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7669 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7670 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7671 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7672 /* Front mixer */
7673 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7674 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7675 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7676 /* Surround mixer */
7677 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7678 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7679 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7680 /* LFE mixer */
7681 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7682 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7683 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7684 /* HP mixer */
7685 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7686 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7687 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7688 /* Front Pin (0x0c) */
7689 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7690 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7691 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7692 /* LFE Pin (0x0e) */
7693 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7694 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7695 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7696 /* HP Pin (0x0f) */
7697 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7698 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7699 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7700 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7701 /* Line In pin */
7702 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7703 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7704
7705 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7706 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7707 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7708 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7709 { }
7710};
7711
7712
7713static struct hda_verb alc885_mba21_init_verbs[] = {
7714 /*Internal and HP Speaker Mixer*/
7715 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7716 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7717 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7718 /*Internal Speaker Pin (0x0c)*/
7719 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
7720 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7721 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7722 /* HP Pin: output 0 (0x0e) */
7723 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7724 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7725 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7726 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
7727 /* Line in (is hp when jack connected)*/
7728 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
7729 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7730
7731 { }
7732 };
7733
7734
7565/* Macbook Pro rev3 */ 7735/* Macbook Pro rev3 */
7566static struct hda_verb alc885_mbp3_init_verbs[] = { 7736static struct hda_verb alc885_mbp3_init_verbs[] = {
7567 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7737 /* Front mixer: unmute input/output amp left and right (volume = 0) */
@@ -7724,54 +7894,35 @@ static void alc885_imac24_setup(struct hda_codec *codec)
7724 spec->autocfg.speaker_pins[1] = 0x1a; 7894 spec->autocfg.speaker_pins[1] = 0x1a;
7725} 7895}
7726 7896
7727static void alc885_mbp3_setup(struct hda_codec *codec) 7897#define alc885_mb5_setup alc885_imac24_setup
7728{ 7898#define alc885_macmini3_setup alc885_imac24_setup
7729 struct alc_spec *spec = codec->spec;
7730
7731 spec->autocfg.hp_pins[0] = 0x15;
7732 spec->autocfg.speaker_pins[0] = 0x14;
7733}
7734 7899
7735static void alc885_mb5_automute(struct hda_codec *codec) 7900/* Macbook Air 2,1 */
7901static void alc885_mba21_setup(struct hda_codec *codec)
7736{ 7902{
7737 unsigned int present; 7903 struct alc_spec *spec = codec->spec;
7738
7739 present = snd_hda_codec_read(codec, 0x14, 0,
7740 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7741 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
7742 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7743 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7744 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7745 7904
7905 spec->autocfg.hp_pins[0] = 0x14;
7906 spec->autocfg.speaker_pins[0] = 0x18;
7746} 7907}
7747 7908
7748static void alc885_mb5_unsol_event(struct hda_codec *codec,
7749 unsigned int res)
7750{
7751 /* Headphone insertion or removal. */
7752 if ((res >> 26) == ALC880_HP_EVENT)
7753 alc885_mb5_automute(codec);
7754}
7755 7909
7756static void alc885_imac91_automute(struct hda_codec *codec)
7757{
7758 unsigned int present;
7759 7910
7760 present = snd_hda_codec_read(codec, 0x14, 0, 7911static void alc885_mbp3_setup(struct hda_codec *codec)
7761 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7912{
7762 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7913 struct alc_spec *spec = codec->spec;
7763 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7764 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7765 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7766 7914
7915 spec->autocfg.hp_pins[0] = 0x15;
7916 spec->autocfg.speaker_pins[0] = 0x14;
7767} 7917}
7768 7918
7769static void alc885_imac91_unsol_event(struct hda_codec *codec, 7919static void alc885_imac91_setup(struct hda_codec *codec)
7770 unsigned int res)
7771{ 7920{
7772 /* Headphone insertion or removal. */ 7921 struct alc_spec *spec = codec->spec;
7773 if ((res >> 26) == ALC880_HP_EVENT) 7922
7774 alc885_imac91_automute(codec); 7923 spec->autocfg.hp_pins[0] = 0x14;
7924 spec->autocfg.speaker_pins[0] = 0x15;
7925 spec->autocfg.speaker_pins[1] = 0x1a;
7775} 7926}
7776 7927
7777static struct hda_verb alc882_targa_verbs[] = { 7928static struct hda_verb alc882_targa_verbs[] = {
@@ -7906,18 +8057,6 @@ static struct hda_verb alc883_auto_init_verbs[] = {
7906 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8057 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7907 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8058 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7908 8059
7909 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7910 * mixer widget
7911 * Note: PASD motherboards uses the Line In 2 as the input for
7912 * front panel mic (mic 2)
7913 */
7914 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7915 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7916 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7917 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7918 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7919 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7920
7921 /* 8060 /*
7922 * Set up output mixers (0x0c - 0x0f) 8061 * Set up output mixers (0x0c - 0x0f)
7923 */ 8062 */
@@ -7942,16 +8081,9 @@ static struct hda_verb alc883_auto_init_verbs[] = {
7942 /* FIXME: use matrix-type input source selection */ 8081 /* FIXME: use matrix-type input source selection */
7943 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8082 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7944 /* Input mixer2 */ 8083 /* Input mixer2 */
7945 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8084 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7946 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7947 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7948 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7949 /* Input mixer3 */ 8085 /* Input mixer3 */
7950 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7951 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7952 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7953 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7954
7955 { } 8087 { }
7956}; 8088};
7957 8089
@@ -8938,6 +9070,8 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
8938 [ALC882_ASUS_A7M] = "asus-a7m", 9070 [ALC882_ASUS_A7M] = "asus-a7m",
8939 [ALC885_MACPRO] = "macpro", 9071 [ALC885_MACPRO] = "macpro",
8940 [ALC885_MB5] = "mb5", 9072 [ALC885_MB5] = "mb5",
9073 [ALC885_MACMINI3] = "macmini3",
9074 [ALC885_MBA21] = "mba21",
8941 [ALC885_MBP3] = "mbp3", 9075 [ALC885_MBP3] = "mbp3",
8942 [ALC885_IMAC24] = "imac24", 9076 [ALC885_IMAC24] = "imac24",
8943 [ALC885_IMAC91] = "imac91", 9077 [ALC885_IMAC91] = "imac91",
@@ -9121,6 +9255,7 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9121 */ 9255 */
9122 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), 9256 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
9123 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5), 9257 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
9258 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
9124 {} /* terminator */ 9259 {} /* terminator */
9125}; 9260};
9126 9261
@@ -9172,6 +9307,18 @@ static struct alc_config_preset alc882_presets[] = {
9172 .input_mux = &alc882_capture_source, 9307 .input_mux = &alc882_capture_source,
9173 .dig_out_nid = ALC882_DIGOUT_NID, 9308 .dig_out_nid = ALC882_DIGOUT_NID,
9174 }, 9309 },
9310 [ALC885_MBA21] = {
9311 .mixers = { alc885_mba21_mixer },
9312 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9313 .num_dacs = 2,
9314 .dac_nids = alc882_dac_nids,
9315 .channel_mode = alc885_mba21_ch_modes,
9316 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9317 .input_mux = &alc882_capture_source,
9318 .unsol_event = alc_automute_amp_unsol_event,
9319 .setup = alc885_mba21_setup,
9320 .init_hook = alc_automute_amp,
9321 },
9175 [ALC885_MBP3] = { 9322 [ALC885_MBP3] = {
9176 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 9323 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9177 .init_verbs = { alc885_mbp3_init_verbs, 9324 .init_verbs = { alc885_mbp3_init_verbs,
@@ -9199,8 +9346,24 @@ static struct alc_config_preset alc882_presets[] = {
9199 .input_mux = &mb5_capture_source, 9346 .input_mux = &mb5_capture_source,
9200 .dig_out_nid = ALC882_DIGOUT_NID, 9347 .dig_out_nid = ALC882_DIGOUT_NID,
9201 .dig_in_nid = ALC882_DIGIN_NID, 9348 .dig_in_nid = ALC882_DIGIN_NID,
9202 .unsol_event = alc885_mb5_unsol_event, 9349 .unsol_event = alc_automute_amp_unsol_event,
9203 .init_hook = alc885_mb5_automute, 9350 .setup = alc885_mb5_setup,
9351 .init_hook = alc_automute_amp,
9352 },
9353 [ALC885_MACMINI3] = {
9354 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9355 .init_verbs = { alc885_macmini3_init_verbs,
9356 alc880_gpio1_init_verbs },
9357 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9358 .dac_nids = alc882_dac_nids,
9359 .channel_mode = alc885_macmini3_6ch_modes,
9360 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9361 .input_mux = &macmini3_capture_source,
9362 .dig_out_nid = ALC882_DIGOUT_NID,
9363 .dig_in_nid = ALC882_DIGIN_NID,
9364 .unsol_event = alc_automute_amp_unsol_event,
9365 .setup = alc885_macmini3_setup,
9366 .init_hook = alc_automute_amp,
9204 }, 9367 },
9205 [ALC885_MACPRO] = { 9368 [ALC885_MACPRO] = {
9206 .mixers = { alc882_macpro_mixer }, 9369 .mixers = { alc882_macpro_mixer },
@@ -9239,8 +9402,9 @@ static struct alc_config_preset alc882_presets[] = {
9239 .input_mux = &alc882_capture_source, 9402 .input_mux = &alc882_capture_source,
9240 .dig_out_nid = ALC882_DIGOUT_NID, 9403 .dig_out_nid = ALC882_DIGOUT_NID,
9241 .dig_in_nid = ALC882_DIGIN_NID, 9404 .dig_in_nid = ALC882_DIGIN_NID,
9242 .unsol_event = alc885_imac91_unsol_event, 9405 .unsol_event = alc_automute_amp_unsol_event,
9243 .init_hook = alc885_imac91_automute, 9406 .setup = alc885_imac91_setup,
9407 .init_hook = alc_automute_amp,
9244 }, 9408 },
9245 [ALC882_TARGA] = { 9409 [ALC882_TARGA] = {
9246 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 9410 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
@@ -9528,7 +9692,7 @@ static struct alc_config_preset alc882_presets[] = {
9528 .setup = alc889_acer_aspire_8930g_setup, 9692 .setup = alc889_acer_aspire_8930g_setup,
9529 .init_hook = alc_automute_amp, 9693 .init_hook = alc_automute_amp,
9530#ifdef CONFIG_SND_HDA_POWER_SAVE 9694#ifdef CONFIG_SND_HDA_POWER_SAVE
9531 .power_hook = alc889_power_eapd, 9695 .power_hook = alc_power_eapd,
9532#endif 9696#endif
9533 }, 9697 },
9534 [ALC888_ACER_ASPIRE_7730G] = { 9698 [ALC888_ACER_ASPIRE_7730G] = {
@@ -10063,7 +10227,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
10063 spec->num_mux_defs = 1; 10227 spec->num_mux_defs = 1;
10064 spec->input_mux = &spec->private_imux[0]; 10228 spec->input_mux = &spec->private_imux[0];
10065 10229
10066 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 10230 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
10067 10231
10068 err = alc_auto_add_mic_boost(codec); 10232 err = alc_auto_add_mic_boost(codec);
10069 if (err < 0) 10233 if (err < 0)
@@ -10201,7 +10365,6 @@ static int patch_alc882(struct hda_codec *codec)
10201 if (!spec->loopback.amplist) 10365 if (!spec->loopback.amplist)
10202 spec->loopback.amplist = alc882_loopbacks; 10366 spec->loopback.amplist = alc882_loopbacks;
10203#endif 10367#endif
10204 codec->proc_widget_hook = print_realtek_coef;
10205 10368
10206 return 0; 10369 return 0;
10207} 10370}
@@ -10324,8 +10487,14 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10324 .info = snd_ctl_boolean_mono_info, \ 10487 .info = snd_ctl_boolean_mono_info, \
10325 .get = alc262_hp_master_sw_get, \ 10488 .get = alc262_hp_master_sw_get, \
10326 .put = alc262_hp_master_sw_put, \ 10489 .put = alc262_hp_master_sw_put, \
10490 }, \
10491 { \
10492 .iface = NID_MAPPING, \
10493 .name = "Master Playback Switch", \
10494 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
10327 } 10495 }
10328 10496
10497
10329static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 10498static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10330 ALC262_HP_MASTER_SWITCH, 10499 ALC262_HP_MASTER_SWITCH,
10331 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -10483,6 +10652,12 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10483 .info = snd_ctl_boolean_mono_info, \ 10652 .info = snd_ctl_boolean_mono_info, \
10484 .get = alc262_hippo_master_sw_get, \ 10653 .get = alc262_hippo_master_sw_get, \
10485 .put = alc262_hippo_master_sw_put, \ 10654 .put = alc262_hippo_master_sw_put, \
10655 }, \
10656 { \
10657 .iface = NID_MAPPING, \
10658 .name = "Master Playback Switch", \
10659 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
10660 (SUBDEV_SPEAKER(0) << 16), \
10486 } 10661 }
10487 10662
10488static struct snd_kcontrol_new alc262_hippo_mixer[] = { 10663static struct snd_kcontrol_new alc262_hippo_mixer[] = {
@@ -10963,11 +11138,17 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10963 { 11138 {
10964 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11139 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10965 .name = "Master Playback Switch", 11140 .name = "Master Playback Switch",
11141 .subdevice = HDA_SUBDEV_AMP_FLAG,
10966 .info = snd_hda_mixer_amp_switch_info, 11142 .info = snd_hda_mixer_amp_switch_info,
10967 .get = snd_hda_mixer_amp_switch_get, 11143 .get = snd_hda_mixer_amp_switch_get,
10968 .put = alc262_fujitsu_master_sw_put, 11144 .put = alc262_fujitsu_master_sw_put,
10969 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 11145 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10970 }, 11146 },
11147 {
11148 .iface = NID_MAPPING,
11149 .name = "Master Playback Switch",
11150 .private_value = 0x1b,
11151 },
10971 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11152 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10972 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11153 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10973 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11154 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
@@ -10998,6 +11179,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10998 { 11179 {
10999 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11180 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11000 .name = "Master Playback Switch", 11181 .name = "Master Playback Switch",
11182 .subdevice = HDA_SUBDEV_AMP_FLAG,
11001 .info = snd_hda_mixer_amp_switch_info, 11183 .info = snd_hda_mixer_amp_switch_info,
11002 .get = snd_hda_mixer_amp_switch_get, 11184 .get = snd_hda_mixer_amp_switch_get,
11003 .put = alc262_lenovo_3000_master_sw_put, 11185 .put = alc262_lenovo_3000_master_sw_put,
@@ -11152,6 +11334,11 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11152 .get = alc_mux_enum_get, 11334 .get = alc_mux_enum_get,
11153 .put = alc262_ultra_mux_enum_put, 11335 .put = alc262_ultra_mux_enum_put,
11154 }, 11336 },
11337 {
11338 .iface = NID_MAPPING,
11339 .name = "Capture Source",
11340 .private_value = 0x15,
11341 },
11155 { } /* end */ 11342 { } /* end */
11156}; 11343};
11157 11344
@@ -11598,7 +11785,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
11598 if (err < 0) 11785 if (err < 0)
11599 return err; 11786 return err;
11600 11787
11601 alc_ssid_check(codec, 0x15, 0x14, 0x1b); 11788 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
11602 11789
11603 return 1; 11790 return 1;
11604} 11791}
@@ -12041,7 +12228,6 @@ static int patch_alc262(struct hda_codec *codec)
12041 if (!spec->loopback.amplist) 12228 if (!spec->loopback.amplist)
12042 spec->loopback.amplist = alc262_loopbacks; 12229 spec->loopback.amplist = alc262_loopbacks;
12043#endif 12230#endif
12044 codec->proc_widget_hook = print_realtek_coef;
12045 12231
12046 return 0; 12232 return 0;
12047} 12233}
@@ -12170,6 +12356,7 @@ static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12170 { 12356 {
12171 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12357 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12172 .name = "Master Playback Switch", 12358 .name = "Master Playback Switch",
12359 .subdevice = HDA_SUBDEV_AMP_FLAG,
12173 .info = snd_hda_mixer_amp_switch_info, 12360 .info = snd_hda_mixer_amp_switch_info,
12174 .get = snd_hda_mixer_amp_switch_get, 12361 .get = snd_hda_mixer_amp_switch_get,
12175 .put = alc268_acer_master_sw_put, 12362 .put = alc268_acer_master_sw_put,
@@ -12185,6 +12372,7 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
12185 { 12372 {
12186 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12373 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12187 .name = "Master Playback Switch", 12374 .name = "Master Playback Switch",
12375 .subdevice = HDA_SUBDEV_AMP_FLAG,
12188 .info = snd_hda_mixer_amp_switch_info, 12376 .info = snd_hda_mixer_amp_switch_info,
12189 .get = snd_hda_mixer_amp_switch_get, 12377 .get = snd_hda_mixer_amp_switch_get,
12190 .put = alc268_acer_master_sw_put, 12378 .put = alc268_acer_master_sw_put,
@@ -12202,6 +12390,7 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12202 { 12390 {
12203 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12391 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12204 .name = "Master Playback Switch", 12392 .name = "Master Playback Switch",
12393 .subdevice = HDA_SUBDEV_AMP_FLAG,
12205 .info = snd_hda_mixer_amp_switch_info, 12394 .info = snd_hda_mixer_amp_switch_info,
12206 .get = snd_hda_mixer_amp_switch_get, 12395 .get = snd_hda_mixer_amp_switch_get,
12207 .put = alc268_acer_master_sw_put, 12396 .put = alc268_acer_master_sw_put,
@@ -12547,7 +12736,6 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12547 dac = 0x02; 12736 dac = 0x02;
12548 break; 12737 break;
12549 case 0x15: 12738 case 0x15:
12550 case 0x21:
12551 dac = 0x03; 12739 dac = 0x03;
12552 break; 12740 break;
12553 default: 12741 default:
@@ -12768,7 +12956,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
12768 if (err < 0) 12956 if (err < 0)
12769 return err; 12957 return err;
12770 12958
12771 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 12959 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12772 12960
12773 return 1; 12961 return 1;
12774} 12962}
@@ -13105,8 +13293,6 @@ static int patch_alc268(struct hda_codec *codec)
13105 if (board_config == ALC268_AUTO) 13293 if (board_config == ALC268_AUTO)
13106 spec->init_hook = alc268_auto_init; 13294 spec->init_hook = alc268_auto_init;
13107 13295
13108 codec->proc_widget_hook = print_realtek_coef;
13109
13110 return 0; 13296 return 0;
13111} 13297}
13112 13298
@@ -13126,6 +13312,15 @@ static hda_nid_t alc269_capsrc_nids[1] = {
13126 0x23, 13312 0x23,
13127}; 13313};
13128 13314
13315static hda_nid_t alc269vb_adc_nids[1] = {
13316 /* ADC1 */
13317 0x09,
13318};
13319
13320static hda_nid_t alc269vb_capsrc_nids[1] = {
13321 0x22,
13322};
13323
13129/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24), 13324/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
13130 * not a mux! 13325 * not a mux!
13131 */ 13326 */
@@ -13155,6 +13350,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13155 { 13350 {
13156 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13157 .name = "Master Playback Switch", 13352 .name = "Master Playback Switch",
13353 .subdevice = HDA_SUBDEV_AMP_FLAG,
13158 .info = snd_hda_mixer_amp_switch_info, 13354 .info = snd_hda_mixer_amp_switch_info,
13159 .get = snd_hda_mixer_amp_switch_get, 13355 .get = snd_hda_mixer_amp_switch_get,
13160 .put = alc268_acer_master_sw_put, 13356 .put = alc268_acer_master_sw_put,
@@ -13175,6 +13371,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13175 { 13371 {
13176 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13372 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13177 .name = "Master Playback Switch", 13373 .name = "Master Playback Switch",
13374 .subdevice = HDA_SUBDEV_AMP_FLAG,
13178 .info = snd_hda_mixer_amp_switch_info, 13375 .info = snd_hda_mixer_amp_switch_info,
13179 .get = snd_hda_mixer_amp_switch_get, 13376 .get = snd_hda_mixer_amp_switch_get,
13180 .put = alc268_acer_master_sw_put, 13377 .put = alc268_acer_master_sw_put,
@@ -13192,7 +13389,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13192 { } 13389 { }
13193}; 13390};
13194 13391
13195static struct snd_kcontrol_new alc269_eeepc_mixer[] = { 13392static struct snd_kcontrol_new alc269_laptop_mixer[] = {
13196 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13393 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13197 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13394 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13198 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13395 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -13200,16 +13397,47 @@ static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
13200 { } /* end */ 13397 { } /* end */
13201}; 13398};
13202 13399
13400static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13401 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13402 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13403 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13404 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13405 { } /* end */
13406};
13407
13203/* capture mixer elements */ 13408/* capture mixer elements */
13204static struct snd_kcontrol_new alc269_epc_capture_mixer[] = { 13409static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13410 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13411 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13412 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13413 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13414 { } /* end */
13415};
13416
13417static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
13205 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 13418 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13206 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 13419 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13207 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13420 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13208 { } /* end */ 13421 { } /* end */
13209}; 13422};
13210 13423
13424static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13425 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13426 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13427 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13428 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13429 { } /* end */
13430};
13431
13432static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13433 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13434 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13435 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13436 { } /* end */
13437};
13438
13211/* FSC amilo */ 13439/* FSC amilo */
13212#define alc269_fujitsu_mixer alc269_eeepc_mixer 13440#define alc269_fujitsu_mixer alc269_laptop_mixer
13213 13441
13214static struct hda_verb alc269_quanta_fl1_verbs[] = { 13442static struct hda_verb alc269_quanta_fl1_verbs[] = {
13215 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13443 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
@@ -13352,7 +13580,7 @@ static void alc269_lifebook_init_hook(struct hda_codec *codec)
13352 alc269_lifebook_mic_autoswitch(codec); 13580 alc269_lifebook_mic_autoswitch(codec);
13353} 13581}
13354 13582
13355static struct hda_verb alc269_eeepc_dmic_init_verbs[] = { 13583static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
13356 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13584 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13357 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 13585 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13358 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 13586 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -13363,7 +13591,7 @@ static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
13363 {} 13591 {}
13364}; 13592};
13365 13593
13366static struct hda_verb alc269_eeepc_amic_init_verbs[] = { 13594static struct hda_verb alc269_laptop_amic_init_verbs[] = {
13367 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13595 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13368 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 13596 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13369 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 13597 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -13373,6 +13601,28 @@ static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
13373 {} 13601 {}
13374}; 13602};
13375 13603
13604static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
13605 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13606 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13607 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13608 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13609 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13610 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13611 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13612 {}
13613};
13614
13615static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
13616 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13617 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
13618 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13619 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13620 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13621 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13622 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13623 {}
13624};
13625
13376/* toggle speaker-output according to the hp-jack state */ 13626/* toggle speaker-output according to the hp-jack state */
13377static void alc269_speaker_automute(struct hda_codec *codec) 13627static void alc269_speaker_automute(struct hda_codec *codec)
13378{ 13628{
@@ -13390,7 +13640,7 @@ static void alc269_speaker_automute(struct hda_codec *codec)
13390} 13640}
13391 13641
13392/* unsolicited event for HP jack sensing */ 13642/* unsolicited event for HP jack sensing */
13393static void alc269_eeepc_unsol_event(struct hda_codec *codec, 13643static void alc269_laptop_unsol_event(struct hda_codec *codec,
13394 unsigned int res) 13644 unsigned int res)
13395{ 13645{
13396 switch (res >> 26) { 13646 switch (res >> 26) {
@@ -13403,7 +13653,7 @@ static void alc269_eeepc_unsol_event(struct hda_codec *codec,
13403 } 13653 }
13404} 13654}
13405 13655
13406static void alc269_eeepc_dmic_setup(struct hda_codec *codec) 13656static void alc269_laptop_dmic_setup(struct hda_codec *codec)
13407{ 13657{
13408 struct alc_spec *spec = codec->spec; 13658 struct alc_spec *spec = codec->spec;
13409 spec->ext_mic.pin = 0x18; 13659 spec->ext_mic.pin = 0x18;
@@ -13413,7 +13663,17 @@ static void alc269_eeepc_dmic_setup(struct hda_codec *codec)
13413 spec->auto_mic = 1; 13663 spec->auto_mic = 1;
13414} 13664}
13415 13665
13416static void alc269_eeepc_amic_setup(struct hda_codec *codec) 13666static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13667{
13668 struct alc_spec *spec = codec->spec;
13669 spec->ext_mic.pin = 0x18;
13670 spec->ext_mic.mux_idx = 0;
13671 spec->int_mic.pin = 0x12;
13672 spec->int_mic.mux_idx = 6;
13673 spec->auto_mic = 1;
13674}
13675
13676static void alc269_laptop_amic_setup(struct hda_codec *codec)
13417{ 13677{
13418 struct alc_spec *spec = codec->spec; 13678 struct alc_spec *spec = codec->spec;
13419 spec->ext_mic.pin = 0x18; 13679 spec->ext_mic.pin = 0x18;
@@ -13423,7 +13683,7 @@ static void alc269_eeepc_amic_setup(struct hda_codec *codec)
13423 spec->auto_mic = 1; 13683 spec->auto_mic = 1;
13424} 13684}
13425 13685
13426static void alc269_eeepc_inithook(struct hda_codec *codec) 13686static void alc269_laptop_inithook(struct hda_codec *codec)
13427{ 13687{
13428 alc269_speaker_automute(codec); 13688 alc269_speaker_automute(codec);
13429 alc_mic_automute(codec); 13689 alc_mic_automute(codec);
@@ -13436,22 +13696,10 @@ static struct hda_verb alc269_init_verbs[] = {
13436 /* 13696 /*
13437 * Unmute ADC0 and set the default input to mic-in 13697 * Unmute ADC0 and set the default input to mic-in
13438 */ 13698 */
13439 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13699 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13440
13441 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
13442 * analog-loopback mixer widget
13443 * Note: PASD motherboards uses the Line In 2 as the input for
13444 * front panel mic (mic 2)
13445 */
13446 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13447 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13448 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13449 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13450 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13451 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13452 13700
13453 /* 13701 /*
13454 * Set up output mixers (0x0c - 0x0e) 13702 * Set up output mixers (0x02 - 0x03)
13455 */ 13703 */
13456 /* set vol=0 to output mixers */ 13704 /* set vol=0 to output mixers */
13457 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13705 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -13476,26 +13724,57 @@ static struct hda_verb alc269_init_verbs[] = {
13476 13724
13477 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13725 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13478 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13726 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13479 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13480 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13481 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13482 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13483 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13484 13727
13485 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 13728 /* FIXME: use Mux-type input source selection */
13486 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 13729 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13730 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13731 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13487 13732
13488 /* FIXME: use matrix-type input source selection */ 13733 /* set EAPD */
13734 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13735 { }
13736};
13737
13738static struct hda_verb alc269vb_init_verbs[] = {
13739 /*
13740 * Unmute ADC0 and set the default input to mic-in
13741 */
13742 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13743
13744 /*
13745 * Set up output mixers (0x02 - 0x03)
13746 */
13747 /* set vol=0 to output mixers */
13748 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13749 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13750
13751 /* set up input amps for analog loopback */
13752 /* Amp Indices: DAC = 0, mixer = 1 */
13753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13754 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13755 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13756 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13757 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13758 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13759
13760 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13761 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13762 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13763 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13764 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13765 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13766 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13767
13768 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13769 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13770
13771 /* FIXME: use Mux-type input source selection */
13489 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 13772 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13490 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 13773 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13491 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13774 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
13492 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13493 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13494 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13495 13775
13496 /* set EAPD */ 13776 /* set EAPD */
13497 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13777 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13498 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13499 { } 13778 { }
13500}; 13779};
13501 13780
@@ -13543,6 +13822,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13543 struct alc_spec *spec = codec->spec; 13822 struct alc_spec *spec = codec->spec;
13544 int err; 13823 int err;
13545 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 13824 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
13825 hda_nid_t real_capsrc_nids;
13546 13826
13547 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 13827 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13548 alc269_ignore); 13828 alc269_ignore);
@@ -13564,11 +13844,20 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13564 if (spec->kctls.list) 13844 if (spec->kctls.list)
13565 add_mixer(spec, spec->kctls.list); 13845 add_mixer(spec, spec->kctls.list);
13566 13846
13567 add_verb(spec, alc269_init_verbs); 13847 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
13848 add_verb(spec, alc269vb_init_verbs);
13849 real_capsrc_nids = alc269vb_capsrc_nids[0];
13850 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
13851 } else {
13852 add_verb(spec, alc269_init_verbs);
13853 real_capsrc_nids = alc269_capsrc_nids[0];
13854 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13855 }
13856
13568 spec->num_mux_defs = 1; 13857 spec->num_mux_defs = 1;
13569 spec->input_mux = &spec->private_imux[0]; 13858 spec->input_mux = &spec->private_imux[0];
13570 /* set default input source */ 13859 /* set default input source */
13571 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0], 13860 snd_hda_codec_write_cache(codec, real_capsrc_nids,
13572 0, AC_VERB_SET_CONNECT_SEL, 13861 0, AC_VERB_SET_CONNECT_SEL,
13573 spec->input_mux->items[0].index); 13862 spec->input_mux->items[0].index);
13574 13863
@@ -13579,8 +13868,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13579 if (!spec->cap_mixer && !spec->no_analog) 13868 if (!spec->cap_mixer && !spec->no_analog)
13580 set_capture_mixer(codec); 13869 set_capture_mixer(codec);
13581 13870
13582 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
13583
13584 return 1; 13871 return 1;
13585} 13872}
13586 13873
@@ -13606,8 +13893,8 @@ static void alc269_auto_init(struct hda_codec *codec)
13606static const char *alc269_models[ALC269_MODEL_LAST] = { 13893static const char *alc269_models[ALC269_MODEL_LAST] = {
13607 [ALC269_BASIC] = "basic", 13894 [ALC269_BASIC] = "basic",
13608 [ALC269_QUANTA_FL1] = "quanta", 13895 [ALC269_QUANTA_FL1] = "quanta",
13609 [ALC269_ASUS_AMIC] = "asus-amic", 13896 [ALC269_AMIC] = "laptop-amic",
13610 [ALC269_ASUS_DMIC] = "asus-dmic", 13897 [ALC269_DMIC] = "laptop-dmic",
13611 [ALC269_FUJITSU] = "fujitsu", 13898 [ALC269_FUJITSU] = "fujitsu",
13612 [ALC269_LIFEBOOK] = "lifebook", 13899 [ALC269_LIFEBOOK] = "lifebook",
13613 [ALC269_AUTO] = "auto", 13900 [ALC269_AUTO] = "auto",
@@ -13616,43 +13903,57 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
13616static struct snd_pci_quirk alc269_cfg_tbl[] = { 13903static struct snd_pci_quirk alc269_cfg_tbl[] = {
13617 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 13904 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
13618 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 13905 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13619 ALC269_ASUS_AMIC), 13906 ALC269_AMIC),
13620 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_ASUS_AMIC), 13907 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
13621 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80JT", ALC269_ASUS_AMIC), 13908 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
13622 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_ASUS_AMIC), 13909 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
13623 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_ASUS_AMIC), 13910 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
13624 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_ASUS_AMIC), 13911 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
13625 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_ASUS_AMIC), 13912 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
13626 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_ASUS_AMIC), 13913 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
13627 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_ASUS_AMIC), 13914 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
13628 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_ASUS_AMIC), 13915 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
13629 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_ASUS_AMIC), 13916 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
13630 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_ASUS_AMIC), 13917 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
13631 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_ASUS_AMIC), 13918 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
13632 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_ASUS_AMIC), 13919 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
13633 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_ASUS_AMIC), 13920 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
13634 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_ASUS_AMIC), 13921 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
13635 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_ASUS_AMIC), 13922 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
13636 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_ASUS_AMIC), 13923 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
13637 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_ASUS_AMIC), 13924 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
13638 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_ASUS_AMIC), 13925 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
13639 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_ASUS_AMIC), 13926 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
13640 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_AMIC), 13927 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
13641 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_ASUS_AMIC), 13928 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
13642 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_AMIC), 13929 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
13643 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_DMIC), 13930 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
13644 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_AMIC), 13931 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
13645 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_AMIC), 13932 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
13646 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_AMIC), 13933 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
13647 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_AMIC), 13934 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
13935 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
13936 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
13937 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
13938 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
13939 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
13940 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
13941 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
13942 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
13648 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", 13943 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13649 ALC269_ASUS_DMIC), 13944 ALC269_DMIC),
13650 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 13945 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13651 ALC269_ASUS_DMIC), 13946 ALC269_DMIC),
13652 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_ASUS_DMIC), 13947 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
13653 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_ASUS_DMIC), 13948 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
13654 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), 13949 SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC),
13655 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), 13950 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13951 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
13952 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
13953 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
13954 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
13955 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
13956 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
13656 {} 13957 {}
13657}; 13958};
13658 13959
@@ -13680,47 +13981,75 @@ static struct alc_config_preset alc269_presets[] = {
13680 .setup = alc269_quanta_fl1_setup, 13981 .setup = alc269_quanta_fl1_setup,
13681 .init_hook = alc269_quanta_fl1_init_hook, 13982 .init_hook = alc269_quanta_fl1_init_hook,
13682 }, 13983 },
13683 [ALC269_ASUS_AMIC] = { 13984 [ALC269_AMIC] = {
13684 .mixers = { alc269_eeepc_mixer }, 13985 .mixers = { alc269_laptop_mixer },
13685 .cap_mixer = alc269_epc_capture_mixer, 13986 .cap_mixer = alc269_laptop_analog_capture_mixer,
13686 .init_verbs = { alc269_init_verbs, 13987 .init_verbs = { alc269_init_verbs,
13687 alc269_eeepc_amic_init_verbs }, 13988 alc269_laptop_amic_init_verbs },
13688 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 13989 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13689 .dac_nids = alc269_dac_nids, 13990 .dac_nids = alc269_dac_nids,
13690 .hp_nid = 0x03, 13991 .hp_nid = 0x03,
13691 .num_channel_mode = ARRAY_SIZE(alc269_modes), 13992 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13692 .channel_mode = alc269_modes, 13993 .channel_mode = alc269_modes,
13693 .unsol_event = alc269_eeepc_unsol_event, 13994 .unsol_event = alc269_laptop_unsol_event,
13694 .setup = alc269_eeepc_amic_setup, 13995 .setup = alc269_laptop_amic_setup,
13695 .init_hook = alc269_eeepc_inithook, 13996 .init_hook = alc269_laptop_inithook,
13696 }, 13997 },
13697 [ALC269_ASUS_DMIC] = { 13998 [ALC269_DMIC] = {
13698 .mixers = { alc269_eeepc_mixer }, 13999 .mixers = { alc269_laptop_mixer },
13699 .cap_mixer = alc269_epc_capture_mixer, 14000 .cap_mixer = alc269_laptop_digital_capture_mixer,
13700 .init_verbs = { alc269_init_verbs, 14001 .init_verbs = { alc269_init_verbs,
13701 alc269_eeepc_dmic_init_verbs }, 14002 alc269_laptop_dmic_init_verbs },
14003 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14004 .dac_nids = alc269_dac_nids,
14005 .hp_nid = 0x03,
14006 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14007 .channel_mode = alc269_modes,
14008 .unsol_event = alc269_laptop_unsol_event,
14009 .setup = alc269_laptop_dmic_setup,
14010 .init_hook = alc269_laptop_inithook,
14011 },
14012 [ALC269VB_AMIC] = {
14013 .mixers = { alc269vb_laptop_mixer },
14014 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14015 .init_verbs = { alc269vb_init_verbs,
14016 alc269vb_laptop_amic_init_verbs },
14017 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14018 .dac_nids = alc269_dac_nids,
14019 .hp_nid = 0x03,
14020 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14021 .channel_mode = alc269_modes,
14022 .unsol_event = alc269_laptop_unsol_event,
14023 .setup = alc269_laptop_amic_setup,
14024 .init_hook = alc269_laptop_inithook,
14025 },
14026 [ALC269VB_DMIC] = {
14027 .mixers = { alc269vb_laptop_mixer },
14028 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14029 .init_verbs = { alc269vb_init_verbs,
14030 alc269vb_laptop_dmic_init_verbs },
13702 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14031 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13703 .dac_nids = alc269_dac_nids, 14032 .dac_nids = alc269_dac_nids,
13704 .hp_nid = 0x03, 14033 .hp_nid = 0x03,
13705 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14034 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13706 .channel_mode = alc269_modes, 14035 .channel_mode = alc269_modes,
13707 .unsol_event = alc269_eeepc_unsol_event, 14036 .unsol_event = alc269_laptop_unsol_event,
13708 .setup = alc269_eeepc_dmic_setup, 14037 .setup = alc269vb_laptop_dmic_setup,
13709 .init_hook = alc269_eeepc_inithook, 14038 .init_hook = alc269_laptop_inithook,
13710 }, 14039 },
13711 [ALC269_FUJITSU] = { 14040 [ALC269_FUJITSU] = {
13712 .mixers = { alc269_fujitsu_mixer }, 14041 .mixers = { alc269_fujitsu_mixer },
13713 .cap_mixer = alc269_epc_capture_mixer, 14042 .cap_mixer = alc269_laptop_digital_capture_mixer,
13714 .init_verbs = { alc269_init_verbs, 14043 .init_verbs = { alc269_init_verbs,
13715 alc269_eeepc_dmic_init_verbs }, 14044 alc269_laptop_dmic_init_verbs },
13716 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14045 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13717 .dac_nids = alc269_dac_nids, 14046 .dac_nids = alc269_dac_nids,
13718 .hp_nid = 0x03, 14047 .hp_nid = 0x03,
13719 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14048 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13720 .channel_mode = alc269_modes, 14049 .channel_mode = alc269_modes,
13721 .unsol_event = alc269_eeepc_unsol_event, 14050 .unsol_event = alc269_laptop_unsol_event,
13722 .setup = alc269_eeepc_dmic_setup, 14051 .setup = alc269_laptop_dmic_setup,
13723 .init_hook = alc269_eeepc_inithook, 14052 .init_hook = alc269_laptop_inithook,
13724 }, 14053 },
13725 [ALC269_LIFEBOOK] = { 14054 [ALC269_LIFEBOOK] = {
13726 .mixers = { alc269_lifebook_mixer }, 14055 .mixers = { alc269_lifebook_mixer },
@@ -13741,6 +14070,7 @@ static int patch_alc269(struct hda_codec *codec)
13741 struct alc_spec *spec; 14070 struct alc_spec *spec;
13742 int board_config; 14071 int board_config;
13743 int err; 14072 int err;
14073 int is_alc269vb = 0;
13744 14074
13745 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 14075 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13746 if (spec == NULL) 14076 if (spec == NULL)
@@ -13757,6 +14087,7 @@ static int patch_alc269(struct hda_codec *codec)
13757 alc_free(codec); 14087 alc_free(codec);
13758 return -ENOMEM; 14088 return -ENOMEM;
13759 } 14089 }
14090 is_alc269vb = 1;
13760 } 14091 }
13761 14092
13762 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 14093 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
@@ -13792,7 +14123,7 @@ static int patch_alc269(struct hda_codec *codec)
13792 if (board_config != ALC269_AUTO) 14123 if (board_config != ALC269_AUTO)
13793 setup_preset(codec, &alc269_presets[board_config]); 14124 setup_preset(codec, &alc269_presets[board_config]);
13794 14125
13795 if (codec->subsystem_id == 0x17aa3bf8) { 14126 if (board_config == ALC269_QUANTA_FL1) {
13796 /* Due to a hardware problem on Lenovo Ideadpad, we need to 14127 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13797 * fix the sample rate of analog I/O to 44.1kHz 14128 * fix the sample rate of analog I/O to 44.1kHz
13798 */ 14129 */
@@ -13805,9 +14136,16 @@ static int patch_alc269(struct hda_codec *codec)
13805 spec->stream_digital_playback = &alc269_pcm_digital_playback; 14136 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13806 spec->stream_digital_capture = &alc269_pcm_digital_capture; 14137 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13807 14138
13808 spec->adc_nids = alc269_adc_nids; 14139 if (!is_alc269vb) {
13809 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 14140 spec->adc_nids = alc269_adc_nids;
13810 spec->capsrc_nids = alc269_capsrc_nids; 14141 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14142 spec->capsrc_nids = alc269_capsrc_nids;
14143 } else {
14144 spec->adc_nids = alc269vb_adc_nids;
14145 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14146 spec->capsrc_nids = alc269vb_capsrc_nids;
14147 }
14148
13811 if (!spec->cap_mixer) 14149 if (!spec->cap_mixer)
13812 set_capture_mixer(codec); 14150 set_capture_mixer(codec);
13813 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 14151 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
@@ -13821,7 +14159,6 @@ static int patch_alc269(struct hda_codec *codec)
13821 if (!spec->loopback.amplist) 14159 if (!spec->loopback.amplist)
13822 spec->loopback.amplist = alc269_loopbacks; 14160 spec->loopback.amplist = alc269_loopbacks;
13823#endif 14161#endif
13824 codec->proc_widget_hook = print_realtek_coef;
13825 14162
13826 return 0; 14163 return 0;
13827} 14164}
@@ -14684,7 +15021,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
14684 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 15021 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14685 set_capture_mixer(codec); 15022 set_capture_mixer(codec);
14686 15023
14687 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b); 15024 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
14688 15025
14689 return 1; 15026 return 1;
14690} 15027}
@@ -14939,13 +15276,16 @@ static int patch_alc861(struct hda_codec *codec)
14939 spec->vmaster_nid = 0x03; 15276 spec->vmaster_nid = 0x03;
14940 15277
14941 codec->patch_ops = alc_patch_ops; 15278 codec->patch_ops = alc_patch_ops;
14942 if (board_config == ALC861_AUTO) 15279 if (board_config == ALC861_AUTO) {
14943 spec->init_hook = alc861_auto_init; 15280 spec->init_hook = alc861_auto_init;
14944#ifdef CONFIG_SND_HDA_POWER_SAVE 15281#ifdef CONFIG_SND_HDA_POWER_SAVE
15282 spec->power_hook = alc_power_eapd;
15283#endif
15284 }
15285#ifdef CONFIG_SND_HDA_POWER_SAVE
14945 if (!spec->loopback.amplist) 15286 if (!spec->loopback.amplist)
14946 spec->loopback.amplist = alc861_loopbacks; 15287 spec->loopback.amplist = alc861_loopbacks;
14947#endif 15288#endif
14948 codec->proc_widget_hook = print_realtek_coef;
14949 15289
14950 return 0; 15290 return 0;
14951} 15291}
@@ -15572,7 +15912,7 @@ static struct alc_config_preset alc861vd_presets[] = {
15572static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, 15912static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
15573 const struct auto_pin_cfg *cfg) 15913 const struct auto_pin_cfg *cfg)
15574{ 15914{
15575 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x22, 0); 15915 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
15576} 15916}
15577 15917
15578 15918
@@ -15808,7 +16148,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
15808 if (err < 0) 16148 if (err < 0)
15809 return err; 16149 return err;
15810 16150
15811 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 16151 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
15812 16152
15813 return 1; 16153 return 1;
15814} 16154}
@@ -15925,7 +16265,6 @@ static int patch_alc861vd(struct hda_codec *codec)
15925 if (!spec->loopback.amplist) 16265 if (!spec->loopback.amplist)
15926 spec->loopback.amplist = alc861vd_loopbacks; 16266 spec->loopback.amplist = alc861vd_loopbacks;
15927#endif 16267#endif
15928 codec->proc_widget_hook = print_realtek_coef;
15929 16268
15930 return 0; 16269 return 0;
15931} 16270}
@@ -16392,13 +16731,6 @@ static struct hda_verb alc662_init_verbs[] = {
16392 /* ADC: mute amp left and right */ 16731 /* ADC: mute amp left and right */
16393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16732 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16394 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16733 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16395 /* Front mixer: unmute input/output amp left and right (volume = 0) */
16396
16397 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16398 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16399 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16400 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16402 16734
16403 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16735 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16404 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16736 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -16448,6 +16780,28 @@ static struct hda_verb alc662_init_verbs[] = {
16448 { } 16780 { }
16449}; 16781};
16450 16782
16783static struct hda_verb alc663_init_verbs[] = {
16784 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16785 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16786 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16787 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16788 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16789 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16790 { }
16791};
16792
16793static struct hda_verb alc272_init_verbs[] = {
16794 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16795 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16796 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16797 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16798 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16799 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16800 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16801 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16802 { }
16803};
16804
16451static struct hda_verb alc662_sue_init_verbs[] = { 16805static struct hda_verb alc662_sue_init_verbs[] = {
16452 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 16806 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16453 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 16807 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
@@ -16467,61 +16821,6 @@ static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
16467 {} 16821 {}
16468}; 16822};
16469 16823
16470/*
16471 * generic initialization of ADC, input mixers and output mixers
16472 */
16473static struct hda_verb alc662_auto_init_verbs[] = {
16474 /*
16475 * Unmute ADC and set the default input to mic-in
16476 */
16477 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16478 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16479
16480 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
16481 * mixer widget
16482 * Note: PASD motherboards uses the Line In 2 as the input for front
16483 * panel mic (mic 2)
16484 */
16485 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16486 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16487 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16488 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16489 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16490 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16491
16492 /*
16493 * Set up output mixers (0x0c - 0x0f)
16494 */
16495 /* set vol=0 to output mixers */
16496 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16497 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16498 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16499
16500 /* set up input amps for analog loopback */
16501 /* Amp Indices: DAC = 0, mixer = 1 */
16502 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16504 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16505 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16506 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16508
16509
16510 /* FIXME: use matrix-type input source selection */
16511 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16512 /* Input mixer */
16513 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16514 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16515 { }
16516};
16517
16518/* additional verbs for ALC663 */
16519static struct hda_verb alc663_auto_init_verbs[] = {
16520 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16521 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16522 { }
16523};
16524
16525static struct hda_verb alc663_m51va_init_verbs[] = { 16824static struct hda_verb alc663_m51va_init_verbs[] = {
16526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16825 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16527 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16826 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -17272,6 +17571,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
17272 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), 17571 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
17273 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), 17572 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
17274 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), 17573 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
17574 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
17275 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), 17575 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
17276 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), 17576 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
17277 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), 17577 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
@@ -17307,6 +17607,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
17307 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), 17607 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
17308 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), 17608 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
17309 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), 17609 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
17610 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
17310 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), 17611 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
17311 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), 17612 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
17312 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), 17613 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
@@ -17334,6 +17635,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
17334 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), 17635 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
17335 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 17636 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
17336 ALC662_3ST_6ch_DIG), 17637 ALC662_3ST_6ch_DIG),
17638 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
17337 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), 17639 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
17338 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), 17640 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
17339 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 17641 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
@@ -17952,15 +18254,23 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
17952 spec->num_mux_defs = 1; 18254 spec->num_mux_defs = 1;
17953 spec->input_mux = &spec->private_imux[0]; 18255 spec->input_mux = &spec->private_imux[0];
17954 18256
17955 add_verb(spec, alc662_auto_init_verbs); 18257 add_verb(spec, alc662_init_verbs);
17956 if (codec->vendor_id == 0x10ec0663) 18258 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
17957 add_verb(spec, alc663_auto_init_verbs); 18259 codec->vendor_id == 0x10ec0665)
18260 add_verb(spec, alc663_init_verbs);
18261
18262 if (codec->vendor_id == 0x10ec0272)
18263 add_verb(spec, alc272_init_verbs);
17958 18264
17959 err = alc_auto_add_mic_boost(codec); 18265 err = alc_auto_add_mic_boost(codec);
17960 if (err < 0) 18266 if (err < 0)
17961 return err; 18267 return err;
17962 18268
17963 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 18269 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18270 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18271 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18272 else
18273 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17964 18274
17965 return 1; 18275 return 1;
17966} 18276}
@@ -18046,11 +18356,20 @@ static int patch_alc662(struct hda_codec *codec)
18046 18356
18047 if (!spec->cap_mixer) 18357 if (!spec->cap_mixer)
18048 set_capture_mixer(codec); 18358 set_capture_mixer(codec);
18049 if (codec->vendor_id == 0x10ec0662) 18359
18360 switch (codec->vendor_id) {
18361 case 0x10ec0662:
18050 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 18362 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18051 else 18363 break;
18364 case 0x10ec0272:
18365 case 0x10ec0663:
18366 case 0x10ec0665:
18052 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 18367 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18053 18368 break;
18369 case 0x10ec0273:
18370 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18371 break;
18372 }
18054 spec->vmaster_nid = 0x02; 18373 spec->vmaster_nid = 0x02;
18055 18374
18056 codec->patch_ops = alc_patch_ops; 18375 codec->patch_ops = alc_patch_ops;
@@ -18060,7 +18379,6 @@ static int patch_alc662(struct hda_codec *codec)
18060 if (!spec->loopback.amplist) 18379 if (!spec->loopback.amplist)
18061 spec->loopback.amplist = alc662_loopbacks; 18380 spec->loopback.amplist = alc662_loopbacks;
18062#endif 18381#endif
18063 codec->proc_widget_hook = print_realtek_coef;
18064 18382
18065 return 0; 18383 return 0;
18066} 18384}
@@ -18101,6 +18419,8 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
18101 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 18419 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
18102 .patch = patch_alc662 }, 18420 .patch = patch_alc662 },
18103 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 18421 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
18422 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
18423 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
18104 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 18424 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
18105 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 18425 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
18106 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 18426 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 43b436c5d01b..f419ee8d75f0 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -122,6 +122,7 @@ static int si3054_switch_put(struct snd_kcontrol *kcontrol,
122#define SI3054_KCONTROL(kname,reg,mask) { \ 122#define SI3054_KCONTROL(kname,reg,mask) { \
123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
124 .name = kname, \ 124 .name = kname, \
125 .subdevice = HDA_SUBDEV_NID_FLAG | reg, \
125 .info = si3054_switch_info, \ 126 .info = si3054_switch_info, \
126 .get = si3054_switch_get, \ 127 .get = si3054_switch_get, \
127 .put = si3054_switch_put, \ 128 .put = si3054_switch_put, \
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 799ba2570902..8c416bb18a57 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -568,6 +568,11 @@ static hda_nid_t stac92hd83xxx_pin_nids[10] = {
568 0x0f, 0x10, 0x11, 0x1f, 0x20, 568 0x0f, 0x10, 0x11, 0x1f, 0x20,
569}; 569};
570 570
571static hda_nid_t stac92hd88xxx_pin_nids[10] = {
572 0x0a, 0x0b, 0x0c, 0x0d,
573 0x0f, 0x11, 0x1f, 0x20,
574};
575
571#define STAC92HD71BXX_NUM_PINS 13 576#define STAC92HD71BXX_NUM_PINS 13
572static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { 577static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = {
573 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 578 0x0a, 0x0b, 0x0c, 0x0d, 0x00,
@@ -2688,7 +2693,7 @@ static struct snd_kcontrol_new *
2688stac_control_new(struct sigmatel_spec *spec, 2693stac_control_new(struct sigmatel_spec *spec,
2689 struct snd_kcontrol_new *ktemp, 2694 struct snd_kcontrol_new *ktemp,
2690 const char *name, 2695 const char *name,
2691 hda_nid_t nid) 2696 unsigned int subdev)
2692{ 2697{
2693 struct snd_kcontrol_new *knew; 2698 struct snd_kcontrol_new *knew;
2694 2699
@@ -2704,8 +2709,7 @@ stac_control_new(struct sigmatel_spec *spec,
2704 spec->kctls.alloced--; 2709 spec->kctls.alloced--;
2705 return NULL; 2710 return NULL;
2706 } 2711 }
2707 if (nid) 2712 knew->subdevice = subdev;
2708 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
2709 return knew; 2713 return knew;
2710} 2714}
2711 2715
@@ -2715,7 +2719,7 @@ static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
2715 unsigned long val) 2719 unsigned long val)
2716{ 2720{
2717 struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name, 2721 struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name,
2718 get_amp_nid_(val)); 2722 HDA_SUBDEV_AMP_FLAG);
2719 if (!knew) 2723 if (!knew)
2720 return -ENOMEM; 2724 return -ENOMEM;
2721 knew->index = idx; 2725 knew->index = idx;
@@ -2874,6 +2878,13 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
2874 2878
2875 conn_len = snd_hda_get_connections(codec, nid, conn, 2879 conn_len = snd_hda_get_connections(codec, nid, conn,
2876 HDA_MAX_CONNECTIONS); 2880 HDA_MAX_CONNECTIONS);
2881 /* 92HD88: trace back up the link of nids to find the DAC */
2882 while (conn_len == 1 && (get_wcaps_type(get_wcaps(codec, conn[0]))
2883 != AC_WID_AUD_OUT)) {
2884 nid = conn[0];
2885 conn_len = snd_hda_get_connections(codec, nid, conn,
2886 HDA_MAX_CONNECTIONS);
2887 }
2877 for (j = 0; j < conn_len; j++) { 2888 for (j = 0; j < conn_len; j++) {
2878 wcaps = get_wcaps(codec, conn[j]); 2889 wcaps = get_wcaps(codec, conn[j]);
2879 wtype = get_wcaps_type(wcaps); 2890 wtype = get_wcaps_type(wcaps);
@@ -4160,34 +4171,52 @@ static void stac92xx_power_down(struct hda_codec *codec)
4160static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, 4171static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
4161 int enable); 4172 int enable);
4162 4173
4174static inline int get_int_hint(struct hda_codec *codec, const char *key,
4175 int *valp)
4176{
4177 const char *p;
4178 p = snd_hda_get_hint(codec, key);
4179 if (p) {
4180 unsigned long val;
4181 if (!strict_strtoul(p, 0, &val)) {
4182 *valp = val;
4183 return 1;
4184 }
4185 }
4186 return 0;
4187}
4188
4163/* override some hints from the hwdep entry */ 4189/* override some hints from the hwdep entry */
4164static void stac_store_hints(struct hda_codec *codec) 4190static void stac_store_hints(struct hda_codec *codec)
4165{ 4191{
4166 struct sigmatel_spec *spec = codec->spec; 4192 struct sigmatel_spec *spec = codec->spec;
4167 const char *p;
4168 int val; 4193 int val;
4169 4194
4170 val = snd_hda_get_bool_hint(codec, "hp_detect"); 4195 val = snd_hda_get_bool_hint(codec, "hp_detect");
4171 if (val >= 0) 4196 if (val >= 0)
4172 spec->hp_detect = val; 4197 spec->hp_detect = val;
4173 p = snd_hda_get_hint(codec, "gpio_mask"); 4198 if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) {
4174 if (p) {
4175 spec->gpio_mask = simple_strtoul(p, NULL, 0);
4176 spec->eapd_mask = spec->gpio_dir = spec->gpio_data = 4199 spec->eapd_mask = spec->gpio_dir = spec->gpio_data =
4177 spec->gpio_mask; 4200 spec->gpio_mask;
4178 } 4201 }
4179 p = snd_hda_get_hint(codec, "gpio_dir"); 4202 if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir))
4180 if (p) 4203 spec->gpio_mask &= spec->gpio_mask;
4181 spec->gpio_dir = simple_strtoul(p, NULL, 0) & spec->gpio_mask; 4204 if (get_int_hint(codec, "gpio_data", &spec->gpio_data))
4182 p = snd_hda_get_hint(codec, "gpio_data"); 4205 spec->gpio_dir &= spec->gpio_mask;
4183 if (p) 4206 if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask))
4184 spec->gpio_data = simple_strtoul(p, NULL, 0) & spec->gpio_mask; 4207 spec->eapd_mask &= spec->gpio_mask;
4185 p = snd_hda_get_hint(codec, "eapd_mask"); 4208 if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute))
4186 if (p) 4209 spec->gpio_mute &= spec->gpio_mask;
4187 spec->eapd_mask = simple_strtoul(p, NULL, 0) & spec->gpio_mask;
4188 val = snd_hda_get_bool_hint(codec, "eapd_switch"); 4210 val = snd_hda_get_bool_hint(codec, "eapd_switch");
4189 if (val >= 0) 4211 if (val >= 0)
4190 spec->eapd_switch = val; 4212 spec->eapd_switch = val;
4213 get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
4214 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
4215 spec->gpio_mask |= spec->gpio_led;
4216 spec->gpio_dir |= spec->gpio_led;
4217 if (spec->gpio_led_polarity)
4218 spec->gpio_data |= spec->gpio_led;
4219 }
4191} 4220}
4192 4221
4193static int stac92xx_init(struct hda_codec *codec) 4222static int stac92xx_init(struct hda_codec *codec)
@@ -4334,6 +4363,12 @@ static int stac92xx_init(struct hda_codec *codec)
4334 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) 4363 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT))
4335 stac_issue_unsol_event(codec, nid); 4364 stac_issue_unsol_event(codec, nid);
4336 } 4365 }
4366
4367#ifdef CONFIG_SND_HDA_POWER_SAVE
4368 /* sync mute LED */
4369 if (spec->gpio_led && codec->patch_ops.check_power_status)
4370 codec->patch_ops.check_power_status(codec, 0x01);
4371#endif
4337 if (spec->dac_list) 4372 if (spec->dac_list)
4338 stac92xx_power_down(codec); 4373 stac92xx_power_down(codec);
4339 return 0; 4374 return 0;
@@ -4372,18 +4407,8 @@ static void stac92xx_free_kctls(struct hda_codec *codec)
4372static void stac92xx_shutup(struct hda_codec *codec) 4407static void stac92xx_shutup(struct hda_codec *codec)
4373{ 4408{
4374 struct sigmatel_spec *spec = codec->spec; 4409 struct sigmatel_spec *spec = codec->spec;
4375 int i;
4376 hda_nid_t nid;
4377 4410
4378 /* reset each pin before powering down DAC/ADC to avoid click noise */ 4411 snd_hda_shutup_pins(codec);
4379 nid = codec->start_nid;
4380 for (i = 0; i < codec->num_nodes; i++, nid++) {
4381 unsigned int wcaps = get_wcaps(codec, nid);
4382 unsigned int wid_type = get_wcaps_type(wcaps);
4383 if (wid_type == AC_WID_PIN)
4384 snd_hda_codec_read(codec, nid, 0,
4385 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
4386 }
4387 4412
4388 if (spec->eapd_mask) 4413 if (spec->eapd_mask)
4389 stac_gpio_set(codec, spec->gpio_mask, 4414 stac_gpio_set(codec, spec->gpio_mask,
@@ -4735,19 +4760,14 @@ static int hp_blike_system(u32 subsystem_id);
4735static void set_hp_led_gpio(struct hda_codec *codec) 4760static void set_hp_led_gpio(struct hda_codec *codec)
4736{ 4761{
4737 struct sigmatel_spec *spec = codec->spec; 4762 struct sigmatel_spec *spec = codec->spec;
4738 switch (codec->vendor_id) { 4763 unsigned int gpio;
4739 case 0x111d7608: 4764
4740 /* GPIO 0 */ 4765 gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
4741 spec->gpio_led = 0x01; 4766 gpio &= AC_GPIO_IO_COUNT;
4742 break; 4767 if (gpio > 3)
4743 case 0x111d7600: 4768 spec->gpio_led = 0x08; /* GPIO 3 */
4744 case 0x111d7601: 4769 else
4745 case 0x111d7602: 4770 spec->gpio_led = 0x01; /* GPIO 0 */
4746 case 0x111d7603:
4747 /* GPIO 3 */
4748 spec->gpio_led = 0x08;
4749 break;
4750 }
4751} 4771}
4752 4772
4753/* 4773/*
@@ -4770,7 +4790,7 @@ static void set_hp_led_gpio(struct hda_codec *codec)
4770 * Need more information on whether it is true across the entire series. 4790 * Need more information on whether it is true across the entire series.
4771 * -- kunal 4791 * -- kunal
4772 */ 4792 */
4773static int find_mute_led_gpio(struct hda_codec *codec) 4793static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
4774{ 4794{
4775 struct sigmatel_spec *spec = codec->spec; 4795 struct sigmatel_spec *spec = codec->spec;
4776 const struct dmi_device *dev = NULL; 4796 const struct dmi_device *dev = NULL;
@@ -4797,7 +4817,7 @@ static int find_mute_led_gpio(struct hda_codec *codec)
4797 */ 4817 */
4798 if (!hp_blike_system(codec->subsystem_id)) { 4818 if (!hp_blike_system(codec->subsystem_id)) {
4799 set_hp_led_gpio(codec); 4819 set_hp_led_gpio(codec);
4800 spec->gpio_led_polarity = 1; 4820 spec->gpio_led_polarity = default_polarity;
4801 return 1; 4821 return 1;
4802 } 4822 }
4803 } 4823 }
@@ -4895,6 +4915,11 @@ static int stac92xx_resume(struct hda_codec *codec)
4895 stac_issue_unsol_event(codec, 4915 stac_issue_unsol_event(codec,
4896 spec->autocfg.line_out_pins[0]); 4916 spec->autocfg.line_out_pins[0]);
4897 } 4917 }
4918#ifdef CONFIG_SND_HDA_POWER_SAVE
4919 /* sync mute LED */
4920 if (spec->gpio_led && codec->patch_ops.check_power_status)
4921 codec->patch_ops.check_power_status(codec, 0x01);
4922#endif
4898 return 0; 4923 return 0;
4899} 4924}
4900 4925
@@ -4914,43 +4939,29 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
4914 hda_nid_t nid) 4939 hda_nid_t nid)
4915{ 4940{
4916 struct sigmatel_spec *spec = codec->spec; 4941 struct sigmatel_spec *spec = codec->spec;
4942 int i, muted = 1;
4917 4943
4918 if (nid == 0x10) { 4944 for (i = 0; i < spec->multiout.num_dacs; i++) {
4919 if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & 4945 nid = spec->multiout.dac_nids[i];
4920 HDA_AMP_MUTE) 4946 if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
4921 spec->gpio_data &= ~spec->gpio_led; /* orange */ 4947 HDA_AMP_MUTE)) {
4922 else 4948 muted = 0; /* something heard */
4923 spec->gpio_data |= spec->gpio_led; /* white */ 4949 break;
4924
4925 if (!spec->gpio_led_polarity) {
4926 /* LED state is inverted on these systems */
4927 spec->gpio_data ^= spec->gpio_led;
4928 } 4950 }
4929
4930 stac_gpio_set(codec, spec->gpio_mask,
4931 spec->gpio_dir,
4932 spec->gpio_data);
4933 } 4951 }
4952 if (muted)
4953 spec->gpio_data &= ~spec->gpio_led; /* orange */
4954 else
4955 spec->gpio_data |= spec->gpio_led; /* white */
4934 4956
4935 return 0; 4957 if (!spec->gpio_led_polarity) {
4936} 4958 /* LED state is inverted on these systems */
4937 4959 spec->gpio_data ^= spec->gpio_led;
4938static int idt92hd83xxx_hp_check_power_status(struct hda_codec *codec, 4960 }
4939 hda_nid_t nid)
4940{
4941 struct sigmatel_spec *spec = codec->spec;
4942 4961
4943 if (nid != 0x13)
4944 return 0;
4945 if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & HDA_AMP_MUTE)
4946 spec->gpio_data |= spec->gpio_led; /* mute LED on */
4947 else
4948 spec->gpio_data &= ~spec->gpio_led; /* mute LED off */
4949 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); 4962 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
4950
4951 return 0; 4963 return 0;
4952} 4964}
4953
4954#endif 4965#endif
4955 4966
4956static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) 4967static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
@@ -5272,7 +5283,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5272 hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; 5283 hda_nid_t conn[STAC92HD83_DAC_COUNT + 1];
5273 int err; 5284 int err;
5274 int num_dacs; 5285 int num_dacs;
5275 hda_nid_t nid;
5276 5286
5277 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5287 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5278 if (spec == NULL) 5288 if (spec == NULL)
@@ -5311,7 +5321,18 @@ again:
5311 stac92hd83xxx_brd_tbl[spec->board_config]); 5321 stac92hd83xxx_brd_tbl[spec->board_config]);
5312 5322
5313 switch (codec->vendor_id) { 5323 switch (codec->vendor_id) {
5324 case 0x111d7666:
5325 case 0x111d7667:
5326 case 0x111d7668:
5327 case 0x111d7669:
5328 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
5329 spec->pin_nids = stac92hd88xxx_pin_nids;
5330 spec->mono_nid = 0;
5331 spec->digbeep_nid = 0;
5332 spec->num_pwrs = 0;
5333 break;
5314 case 0x111d7604: 5334 case 0x111d7604:
5335 case 0x111d76d4:
5315 case 0x111d7605: 5336 case 0x111d7605:
5316 case 0x111d76d5: 5337 case 0x111d76d5:
5317 if (spec->board_config == STAC_92HD83XXX_PWR_REF) 5338 if (spec->board_config == STAC_92HD83XXX_PWR_REF)
@@ -5322,8 +5343,10 @@ again:
5322 5343
5323 codec->patch_ops = stac92xx_patch_ops; 5344 codec->patch_ops = stac92xx_patch_ops;
5324 5345
5325 if (spec->board_config == STAC_92HD83XXX_HP) 5346 if (find_mute_led_gpio(codec, 0))
5326 spec->gpio_led = 0x01; 5347 snd_printd("mute LED gpio %d polarity %d\n",
5348 spec->gpio_led,
5349 spec->gpio_led_polarity);
5327 5350
5328#ifdef CONFIG_SND_HDA_POWER_SAVE 5351#ifdef CONFIG_SND_HDA_POWER_SAVE
5329 if (spec->gpio_led) { 5352 if (spec->gpio_led) {
@@ -5332,7 +5355,7 @@ again:
5332 spec->gpio_data |= spec->gpio_led; 5355 spec->gpio_data |= spec->gpio_led;
5333 /* register check_power_status callback. */ 5356 /* register check_power_status callback. */
5334 codec->patch_ops.check_power_status = 5357 codec->patch_ops.check_power_status =
5335 idt92hd83xxx_hp_check_power_status; 5358 stac92xx_hp_check_power_status;
5336 } 5359 }
5337#endif 5360#endif
5338 5361
@@ -5352,24 +5375,21 @@ again:
5352 return err; 5375 return err;
5353 } 5376 }
5354 5377
5355 switch (spec->board_config) { 5378 /* docking output support */
5356 case STAC_DELL_S14: 5379 num_dacs = snd_hda_get_connections(codec, 0xF,
5357 nid = 0xf;
5358 break;
5359 default:
5360 nid = 0xe;
5361 break;
5362 }
5363
5364 num_dacs = snd_hda_get_connections(codec, nid,
5365 conn, STAC92HD83_DAC_COUNT + 1) - 1; 5380 conn, STAC92HD83_DAC_COUNT + 1) - 1;
5366 if (num_dacs < 0) 5381 /* skip non-DAC connections */
5367 num_dacs = STAC92HD83_DAC_COUNT; 5382 while (num_dacs >= 0 &&
5368 5383 (get_wcaps_type(get_wcaps(codec, conn[num_dacs]))
5369 /* set port X to select the last DAC 5384 != AC_WID_AUD_OUT))
5370 */ 5385 num_dacs--;
5371 snd_hda_codec_write_cache(codec, nid, 0, 5386 /* set port E and F to select the last DAC */
5387 if (num_dacs >= 0) {
5388 snd_hda_codec_write_cache(codec, 0xE, 0,
5389 AC_VERB_SET_CONNECT_SEL, num_dacs);
5390 snd_hda_codec_write_cache(codec, 0xF, 0,
5372 AC_VERB_SET_CONNECT_SEL, num_dacs); 5391 AC_VERB_SET_CONNECT_SEL, num_dacs);
5392 }
5373 5393
5374 codec->proc_widget_hook = stac92hd_proc_hook; 5394 codec->proc_widget_hook = stac92hd_proc_hook;
5375 5395
@@ -5431,6 +5451,54 @@ static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec,
5431 return 0; 5451 return 0;
5432} 5452}
5433 5453
5454/* HP dv7 bass switch - GPIO5 */
5455#define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info
5456static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol,
5457 struct snd_ctl_elem_value *ucontrol)
5458{
5459 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5460 struct sigmatel_spec *spec = codec->spec;
5461 ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20);
5462 return 0;
5463}
5464
5465static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
5466 struct snd_ctl_elem_value *ucontrol)
5467{
5468 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5469 struct sigmatel_spec *spec = codec->spec;
5470 unsigned int gpio_data;
5471
5472 gpio_data = (spec->gpio_data & ~0x20) |
5473 (ucontrol->value.integer.value[0] ? 0x20 : 0);
5474 if (gpio_data == spec->gpio_data)
5475 return 0;
5476 spec->gpio_data = gpio_data;
5477 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
5478 return 1;
5479}
5480
5481static struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
5482 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5483 .info = stac_hp_bass_gpio_info,
5484 .get = stac_hp_bass_gpio_get,
5485 .put = stac_hp_bass_gpio_put,
5486};
5487
5488static int stac_add_hp_bass_switch(struct hda_codec *codec)
5489{
5490 struct sigmatel_spec *spec = codec->spec;
5491
5492 if (!stac_control_new(spec, &stac_hp_bass_sw_ctrl,
5493 "Bass Speaker Playback Switch", 0))
5494 return -ENOMEM;
5495
5496 spec->gpio_mask |= 0x20;
5497 spec->gpio_dir |= 0x20;
5498 spec->gpio_data |= 0x20;
5499 return 0;
5500}
5501
5434static int patch_stac92hd71bxx(struct hda_codec *codec) 5502static int patch_stac92hd71bxx(struct hda_codec *codec)
5435{ 5503{
5436 struct sigmatel_spec *spec; 5504 struct sigmatel_spec *spec;
@@ -5602,7 +5670,6 @@ again:
5602 */ 5670 */
5603 spec->num_smuxes = 1; 5671 spec->num_smuxes = 1;
5604 spec->num_dmuxes = 1; 5672 spec->num_dmuxes = 1;
5605 spec->gpio_led = 0x01;
5606 /* fallthrough */ 5673 /* fallthrough */
5607 case STAC_HP_DV5: 5674 case STAC_HP_DV5:
5608 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); 5675 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
@@ -5617,8 +5684,6 @@ again:
5617 spec->num_dmics = 1; 5684 spec->num_dmics = 1;
5618 spec->num_dmuxes = 1; 5685 spec->num_dmuxes = 1;
5619 spec->num_smuxes = 1; 5686 spec->num_smuxes = 1;
5620 /* orange/white mute led on GPIO3, orange=0, white=1 */
5621 spec->gpio_led = 0x08;
5622 break; 5687 break;
5623 } 5688 }
5624 5689
@@ -5640,7 +5705,7 @@ again:
5640 } 5705 }
5641 } 5706 }
5642 5707
5643 if (find_mute_led_gpio(codec)) 5708 if (find_mute_led_gpio(codec, 1))
5644 snd_printd("mute LED gpio %d polarity %d\n", 5709 snd_printd("mute LED gpio %d polarity %d\n",
5645 spec->gpio_led, 5710 spec->gpio_led,
5646 spec->gpio_led_polarity); 5711 spec->gpio_led_polarity);
@@ -5674,6 +5739,15 @@ again:
5674 return err; 5739 return err;
5675 } 5740 }
5676 5741
5742 /* enable bass on HP dv7 */
5743 if (spec->board_config == STAC_HP_DV5) {
5744 unsigned int cap;
5745 cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
5746 cap &= AC_GPIO_IO_COUNT;
5747 if (cap >= 6)
5748 stac_add_hp_bass_switch(codec);
5749 }
5750
5677 codec->proc_widget_hook = stac92hd7x_proc_hook; 5751 codec->proc_widget_hook = stac92hd7x_proc_hook;
5678 5752
5679 return 0; 5753 return 0;
@@ -6172,8 +6246,13 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = {
6172 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, 6246 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
6173 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, 6247 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
6174 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, 6248 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx},
6249 { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx},
6175 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, 6250 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
6176 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx}, 6251 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx},
6252 { .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx},
6253 { .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx},
6254 { .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx},
6255 { .id = 0x111d7669, .name = "92HD88B4", .patch = patch_stac92hd83xxx},
6177 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, 6256 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
6178 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, 6257 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
6179 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, 6258 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index b70e26ad263f..9ddc37300f6b 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -54,6 +54,8 @@
54#include "hda_codec.h" 54#include "hda_codec.h"
55#include "hda_local.h" 55#include "hda_local.h"
56 56
57#define NID_MAPPING (-1)
58
57/* amp values */ 59/* amp values */
58#define AMP_VAL_IDX_SHIFT 19 60#define AMP_VAL_IDX_SHIFT 19
59#define AMP_VAL_IDX_MASK (0x0f<<19) 61#define AMP_VAL_IDX_MASK (0x0f<<19)
@@ -157,6 +159,19 @@ struct via_spec {
157#endif 159#endif
158}; 160};
159 161
162static struct via_spec * via_new_spec(struct hda_codec *codec)
163{
164 struct via_spec *spec;
165
166 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
167 if (spec == NULL)
168 return NULL;
169
170 codec->spec = spec;
171 spec->codec = codec;
172 return spec;
173}
174
160static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) 175static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
161{ 176{
162 u32 vendor_id = codec->vendor_id; 177 u32 vendor_id = codec->vendor_id;
@@ -443,11 +458,27 @@ static int via_add_control(struct via_spec *spec, int type, const char *name,
443 if (!knew->name) 458 if (!knew->name)
444 return -ENOMEM; 459 return -ENOMEM;
445 if (get_amp_nid_(val)) 460 if (get_amp_nid_(val))
446 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 461 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
447 knew->private_value = val; 462 knew->private_value = val;
448 return 0; 463 return 0;
449} 464}
450 465
466static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
467 struct snd_kcontrol_new *tmpl)
468{
469 struct snd_kcontrol_new *knew;
470
471 snd_array_init(&spec->kctls, sizeof(*knew), 32);
472 knew = snd_array_new(&spec->kctls);
473 if (!knew)
474 return NULL;
475 *knew = *tmpl;
476 knew->name = kstrdup(tmpl->name, GFP_KERNEL);
477 if (!knew->name)
478 return NULL;
479 return 0;
480}
481
451static void via_free_kctls(struct hda_codec *codec) 482static void via_free_kctls(struct hda_codec *codec)
452{ 483{
453 struct via_spec *spec = codec->spec; 484 struct via_spec *spec = codec->spec;
@@ -1088,24 +1119,9 @@ static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
1088 struct snd_ctl_elem_value *ucontrol) 1119 struct snd_ctl_elem_value *ucontrol)
1089{ 1120{
1090 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1121 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1091 struct via_spec *spec = codec->spec; 1122 hda_nid_t nid = kcontrol->private_value;
1092 hda_nid_t nid;
1093 unsigned int pinsel; 1123 unsigned int pinsel;
1094 1124
1095 switch (spec->codec_type) {
1096 case VT1718S:
1097 nid = 0x34;
1098 break;
1099 case VT2002P:
1100 nid = 0x35;
1101 break;
1102 case VT1812:
1103 nid = 0x3d;
1104 break;
1105 default:
1106 nid = spec->autocfg.hp_pins[0];
1107 break;
1108 }
1109 /* use !! to translate conn sel 2 for VT1718S */ 1125 /* use !! to translate conn sel 2 for VT1718S */
1110 pinsel = !!snd_hda_codec_read(codec, nid, 0, 1126 pinsel = !!snd_hda_codec_read(codec, nid, 0,
1111 AC_VERB_GET_CONNECT_SEL, 1127 AC_VERB_GET_CONNECT_SEL,
@@ -1127,29 +1143,24 @@ static void activate_ctl(struct hda_codec *codec, const char *name, int active)
1127 } 1143 }
1128} 1144}
1129 1145
1146static hda_nid_t side_mute_channel(struct via_spec *spec)
1147{
1148 switch (spec->codec_type) {
1149 case VT1708: return 0x1b;
1150 case VT1709_10CH: return 0x29;
1151 case VT1708B_8CH: /* fall thru */
1152 case VT1708S: return 0x27;
1153 default: return 0;
1154 }
1155}
1156
1130static int update_side_mute_status(struct hda_codec *codec) 1157static int update_side_mute_status(struct hda_codec *codec)
1131{ 1158{
1132 /* mute side channel */ 1159 /* mute side channel */
1133 struct via_spec *spec = codec->spec; 1160 struct via_spec *spec = codec->spec;
1134 unsigned int parm = spec->hp_independent_mode 1161 unsigned int parm = spec->hp_independent_mode
1135 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE; 1162 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
1136 hda_nid_t sw3; 1163 hda_nid_t sw3 = side_mute_channel(spec);
1137
1138 switch (spec->codec_type) {
1139 case VT1708:
1140 sw3 = 0x1b;
1141 break;
1142 case VT1709_10CH:
1143 sw3 = 0x29;
1144 break;
1145 case VT1708B_8CH:
1146 case VT1708S:
1147 sw3 = 0x27;
1148 break;
1149 default:
1150 sw3 = 0;
1151 break;
1152 }
1153 1164
1154 if (sw3) 1165 if (sw3)
1155 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE, 1166 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE,
@@ -1162,28 +1173,11 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1162{ 1173{
1163 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1174 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1164 struct via_spec *spec = codec->spec; 1175 struct via_spec *spec = codec->spec;
1165 hda_nid_t nid = spec->autocfg.hp_pins[0]; 1176 hda_nid_t nid = kcontrol->private_value;
1166 unsigned int pinsel = ucontrol->value.enumerated.item[0]; 1177 unsigned int pinsel = ucontrol->value.enumerated.item[0];
1167 /* Get Independent Mode index of headphone pin widget */ 1178 /* Get Independent Mode index of headphone pin widget */
1168 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel 1179 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
1169 ? 1 : 0; 1180 ? 1 : 0;
1170
1171 switch (spec->codec_type) {
1172 case VT1718S:
1173 nid = 0x34;
1174 pinsel = pinsel ? 2 : 0; /* indep HP use AOW4 (index 2) */
1175 spec->multiout.num_dacs = 4;
1176 break;
1177 case VT2002P:
1178 nid = 0x35;
1179 break;
1180 case VT1812:
1181 nid = 0x3d;
1182 break;
1183 default:
1184 nid = spec->autocfg.hp_pins[0];
1185 break;
1186 }
1187 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel); 1181 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel);
1188 1182
1189 if (spec->multiout.hp_nid && spec->multiout.hp_nid 1183 if (spec->multiout.hp_nid && spec->multiout.hp_nid
@@ -1207,18 +1201,55 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1207 return 0; 1201 return 0;
1208} 1202}
1209 1203
1210static struct snd_kcontrol_new via_hp_mixer[] = { 1204static struct snd_kcontrol_new via_hp_mixer[2] = {
1211 { 1205 {
1212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1213 .name = "Independent HP", 1207 .name = "Independent HP",
1214 .count = 1,
1215 .info = via_independent_hp_info, 1208 .info = via_independent_hp_info,
1216 .get = via_independent_hp_get, 1209 .get = via_independent_hp_get,
1217 .put = via_independent_hp_put, 1210 .put = via_independent_hp_put,
1218 }, 1211 },
1219 { } /* end */ 1212 {
1213 .iface = NID_MAPPING,
1214 .name = "Independent HP",
1215 },
1220}; 1216};
1221 1217
1218static int via_hp_build(struct via_spec *spec)
1219{
1220 struct snd_kcontrol_new *knew;
1221 hda_nid_t nid;
1222
1223 knew = via_clone_control(spec, &via_hp_mixer[0]);
1224 if (knew == NULL)
1225 return -ENOMEM;
1226
1227 switch (spec->codec_type) {
1228 case VT1718S:
1229 nid = 0x34;
1230 break;
1231 case VT2002P:
1232 nid = 0x35;
1233 break;
1234 case VT1812:
1235 nid = 0x3d;
1236 break;
1237 default:
1238 nid = spec->autocfg.hp_pins[0];
1239 break;
1240 }
1241
1242 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
1243 knew->private_value = nid;
1244
1245 knew = via_clone_control(spec, &via_hp_mixer[1]);
1246 if (knew == NULL)
1247 return -ENOMEM;
1248 knew->subdevice = side_mute_channel(spec);
1249
1250 return 0;
1251}
1252
1222static void notify_aa_path_ctls(struct hda_codec *codec) 1253static void notify_aa_path_ctls(struct hda_codec *codec)
1223{ 1254{
1224 int i; 1255 int i;
@@ -1376,7 +1407,7 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
1376 return 1; 1407 return 1;
1377} 1408}
1378 1409
1379static struct snd_kcontrol_new via_smart51_mixer[] = { 1410static struct snd_kcontrol_new via_smart51_mixer[2] = {
1380 { 1411 {
1381 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1412 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1382 .name = "Smart 5.1", 1413 .name = "Smart 5.1",
@@ -1385,9 +1416,36 @@ static struct snd_kcontrol_new via_smart51_mixer[] = {
1385 .get = via_smart51_get, 1416 .get = via_smart51_get,
1386 .put = via_smart51_put, 1417 .put = via_smart51_put,
1387 }, 1418 },
1388 {} /* end */ 1419 {
1420 .iface = NID_MAPPING,
1421 .name = "Smart 5.1",
1422 }
1389}; 1423};
1390 1424
1425static int via_smart51_build(struct via_spec *spec)
1426{
1427 struct snd_kcontrol_new *knew;
1428 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1429 hda_nid_t nid;
1430 int i;
1431
1432 knew = via_clone_control(spec, &via_smart51_mixer[0]);
1433 if (knew == NULL)
1434 return -ENOMEM;
1435
1436 for (i = 0; i < ARRAY_SIZE(index); i++) {
1437 nid = spec->autocfg.input_pins[index[i]];
1438 if (nid) {
1439 knew = via_clone_control(spec, &via_smart51_mixer[1]);
1440 if (knew == NULL)
1441 return -ENOMEM;
1442 knew->subdevice = nid;
1443 }
1444 }
1445
1446 return 0;
1447}
1448
1391/* capture mixer elements */ 1449/* capture mixer elements */
1392static struct snd_kcontrol_new vt1708_capture_mixer[] = { 1450static struct snd_kcontrol_new vt1708_capture_mixer[] = {
1393 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), 1451 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
@@ -1819,8 +1877,9 @@ static struct hda_pcm_stream vt1708_pcm_digital_capture = {
1819static int via_build_controls(struct hda_codec *codec) 1877static int via_build_controls(struct hda_codec *codec)
1820{ 1878{
1821 struct via_spec *spec = codec->spec; 1879 struct via_spec *spec = codec->spec;
1822 int err; 1880 struct snd_kcontrol *kctl;
1823 int i; 1881 struct snd_kcontrol_new *knew;
1882 int err, i;
1824 1883
1825 for (i = 0; i < spec->num_mixers; i++) { 1884 for (i = 0; i < spec->num_mixers; i++) {
1826 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1885 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
@@ -1845,6 +1904,27 @@ static int via_build_controls(struct hda_codec *codec)
1845 return err; 1904 return err;
1846 } 1905 }
1847 1906
1907 /* assign Capture Source enums to NID */
1908 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1909 for (i = 0; kctl && i < kctl->count; i++) {
1910 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
1911 if (err < 0)
1912 return err;
1913 }
1914
1915 /* other nid->control mapping */
1916 for (i = 0; i < spec->num_mixers; i++) {
1917 for (knew = spec->mixers[i]; knew->name; knew++) {
1918 if (knew->iface != NID_MAPPING)
1919 continue;
1920 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1921 if (kctl == NULL)
1922 continue;
1923 err = snd_hda_add_nid(codec, kctl, 0,
1924 knew->subdevice);
1925 }
1926 }
1927
1848 /* init power states */ 1928 /* init power states */
1849 set_jack_power_state(codec); 1929 set_jack_power_state(codec);
1850 analog_low_current_mode(codec, 1); 1930 analog_low_current_mode(codec, 1);
@@ -2481,9 +2561,9 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
2481 spec->input_mux = &spec->private_imux[0]; 2561 spec->input_mux = &spec->private_imux[0];
2482 2562
2483 if (spec->hp_mux) 2563 if (spec->hp_mux)
2484 spec->mixers[spec->num_mixers++] = via_hp_mixer; 2564 via_hp_build(spec);
2485 2565
2486 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 2566 via_smart51_build(spec);
2487 return 1; 2567 return 1;
2488} 2568}
2489 2569
@@ -2554,12 +2634,10 @@ static int patch_vt1708(struct hda_codec *codec)
2554 int err; 2634 int err;
2555 2635
2556 /* create a codec specific record */ 2636 /* create a codec specific record */
2557 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 2637 spec = via_new_spec(codec);
2558 if (spec == NULL) 2638 if (spec == NULL)
2559 return -ENOMEM; 2639 return -ENOMEM;
2560 2640
2561 codec->spec = spec;
2562
2563 /* automatic parse from the BIOS config */ 2641 /* automatic parse from the BIOS config */
2564 err = vt1708_parse_auto_config(codec); 2642 err = vt1708_parse_auto_config(codec);
2565 if (err < 0) { 2643 if (err < 0) {
@@ -2597,7 +2675,6 @@ static int patch_vt1708(struct hda_codec *codec)
2597#ifdef CONFIG_SND_HDA_POWER_SAVE 2675#ifdef CONFIG_SND_HDA_POWER_SAVE
2598 spec->loopback.amplist = vt1708_loopbacks; 2676 spec->loopback.amplist = vt1708_loopbacks;
2599#endif 2677#endif
2600 spec->codec = codec;
2601 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state); 2678 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2602 return 0; 2679 return 0;
2603} 2680}
@@ -3010,9 +3087,9 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
3010 spec->input_mux = &spec->private_imux[0]; 3087 spec->input_mux = &spec->private_imux[0];
3011 3088
3012 if (spec->hp_mux) 3089 if (spec->hp_mux)
3013 spec->mixers[spec->num_mixers++] = via_hp_mixer; 3090 via_hp_build(spec);
3014 3091
3015 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 3092 via_smart51_build(spec);
3016 return 1; 3093 return 1;
3017} 3094}
3018 3095
@@ -3032,12 +3109,10 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
3032 int err; 3109 int err;
3033 3110
3034 /* create a codec specific record */ 3111 /* create a codec specific record */
3035 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3112 spec = via_new_spec(codec);
3036 if (spec == NULL) 3113 if (spec == NULL)
3037 return -ENOMEM; 3114 return -ENOMEM;
3038 3115
3039 codec->spec = spec;
3040
3041 err = vt1709_parse_auto_config(codec); 3116 err = vt1709_parse_auto_config(codec);
3042 if (err < 0) { 3117 if (err < 0) {
3043 via_free(codec); 3118 via_free(codec);
@@ -3126,12 +3201,10 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
3126 int err; 3201 int err;
3127 3202
3128 /* create a codec specific record */ 3203 /* create a codec specific record */
3129 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3204 spec = via_new_spec(codec);
3130 if (spec == NULL) 3205 if (spec == NULL)
3131 return -ENOMEM; 3206 return -ENOMEM;
3132 3207
3133 codec->spec = spec;
3134
3135 err = vt1709_parse_auto_config(codec); 3208 err = vt1709_parse_auto_config(codec);
3136 if (err < 0) { 3209 if (err < 0) {
3137 via_free(codec); 3210 via_free(codec);
@@ -3581,9 +3654,9 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
3581 spec->input_mux = &spec->private_imux[0]; 3654 spec->input_mux = &spec->private_imux[0];
3582 3655
3583 if (spec->hp_mux) 3656 if (spec->hp_mux)
3584 spec->mixers[spec->num_mixers++] = via_hp_mixer; 3657 via_hp_build(spec);
3585 3658
3586 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 3659 via_smart51_build(spec);
3587 return 1; 3660 return 1;
3588} 3661}
3589 3662
@@ -3605,12 +3678,10 @@ static int patch_vt1708B_8ch(struct hda_codec *codec)
3605 if (get_codec_type(codec) == VT1708BCE) 3678 if (get_codec_type(codec) == VT1708BCE)
3606 return patch_vt1708S(codec); 3679 return patch_vt1708S(codec);
3607 /* create a codec specific record */ 3680 /* create a codec specific record */
3608 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3681 spec = via_new_spec(codec);
3609 if (spec == NULL) 3682 if (spec == NULL)
3610 return -ENOMEM; 3683 return -ENOMEM;
3611 3684
3612 codec->spec = spec;
3613
3614 /* automatic parse from the BIOS config */ 3685 /* automatic parse from the BIOS config */
3615 err = vt1708B_parse_auto_config(codec); 3686 err = vt1708B_parse_auto_config(codec);
3616 if (err < 0) { 3687 if (err < 0) {
@@ -3657,12 +3728,10 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
3657 int err; 3728 int err;
3658 3729
3659 /* create a codec specific record */ 3730 /* create a codec specific record */
3660 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3731 spec = via_new_spec(codec);
3661 if (spec == NULL) 3732 if (spec == NULL)
3662 return -ENOMEM; 3733 return -ENOMEM;
3663 3734
3664 codec->spec = spec;
3665
3666 /* automatic parse from the BIOS config */ 3735 /* automatic parse from the BIOS config */
3667 err = vt1708B_parse_auto_config(codec); 3736 err = vt1708B_parse_auto_config(codec);
3668 if (err < 0) { 3737 if (err < 0) {
@@ -4071,9 +4140,9 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
4071 spec->input_mux = &spec->private_imux[0]; 4140 spec->input_mux = &spec->private_imux[0];
4072 4141
4073 if (spec->hp_mux) 4142 if (spec->hp_mux)
4074 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4143 via_hp_build(spec);
4075 4144
4076 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 4145 via_smart51_build(spec);
4077 return 1; 4146 return 1;
4078} 4147}
4079 4148
@@ -4103,12 +4172,10 @@ static int patch_vt1708S(struct hda_codec *codec)
4103 int err; 4172 int err;
4104 4173
4105 /* create a codec specific record */ 4174 /* create a codec specific record */
4106 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4175 spec = via_new_spec(codec);
4107 if (spec == NULL) 4176 if (spec == NULL)
4108 return -ENOMEM; 4177 return -ENOMEM;
4109 4178
4110 codec->spec = spec;
4111
4112 /* automatic parse from the BIOS config */ 4179 /* automatic parse from the BIOS config */
4113 err = vt1708S_parse_auto_config(codec); 4180 err = vt1708S_parse_auto_config(codec);
4114 if (err < 0) { 4181 if (err < 0) {
@@ -4443,7 +4510,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
4443 spec->input_mux = &spec->private_imux[0]; 4510 spec->input_mux = &spec->private_imux[0];
4444 4511
4445 if (spec->hp_mux) 4512 if (spec->hp_mux)
4446 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4513 via_hp_build(spec);
4447 4514
4448 return 1; 4515 return 1;
4449} 4516}
@@ -4464,12 +4531,10 @@ static int patch_vt1702(struct hda_codec *codec)
4464 int err; 4531 int err;
4465 4532
4466 /* create a codec specific record */ 4533 /* create a codec specific record */
4467 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4534 spec = via_new_spec(codec);
4468 if (spec == NULL) 4535 if (spec == NULL)
4469 return -ENOMEM; 4536 return -ENOMEM;
4470 4537
4471 codec->spec = spec;
4472
4473 /* automatic parse from the BIOS config */ 4538 /* automatic parse from the BIOS config */
4474 err = vt1702_parse_auto_config(codec); 4539 err = vt1702_parse_auto_config(codec);
4475 if (err < 0) { 4540 if (err < 0) {
@@ -4865,9 +4930,9 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec)
4865 spec->input_mux = &spec->private_imux[0]; 4930 spec->input_mux = &spec->private_imux[0];
4866 4931
4867 if (spec->hp_mux) 4932 if (spec->hp_mux)
4868 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4933 via_hp_build(spec);
4869 4934
4870 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 4935 via_smart51_build(spec);
4871 4936
4872 return 1; 4937 return 1;
4873} 4938}
@@ -4888,12 +4953,10 @@ static int patch_vt1718S(struct hda_codec *codec)
4888 int err; 4953 int err;
4889 4954
4890 /* create a codec specific record */ 4955 /* create a codec specific record */
4891 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4956 spec = via_new_spec(codec);
4892 if (spec == NULL) 4957 if (spec == NULL)
4893 return -ENOMEM; 4958 return -ENOMEM;
4894 4959
4895 codec->spec = spec;
4896
4897 /* automatic parse from the BIOS config */ 4960 /* automatic parse from the BIOS config */
4898 err = vt1718S_parse_auto_config(codec); 4961 err = vt1718S_parse_auto_config(codec);
4899 if (err < 0) { 4962 if (err < 0) {
@@ -5014,6 +5077,7 @@ static struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
5014 { 5077 {
5015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5078 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5016 .name = "Digital Mic Capture Switch", 5079 .name = "Digital Mic Capture Switch",
5080 .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
5017 .count = 1, 5081 .count = 1,
5018 .info = vt1716s_dmic_info, 5082 .info = vt1716s_dmic_info,
5019 .get = vt1716s_dmic_get, 5083 .get = vt1716s_dmic_get,
@@ -5361,9 +5425,9 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec)
5361 spec->input_mux = &spec->private_imux[0]; 5425 spec->input_mux = &spec->private_imux[0];
5362 5426
5363 if (spec->hp_mux) 5427 if (spec->hp_mux)
5364 spec->mixers[spec->num_mixers++] = via_hp_mixer; 5428 via_hp_build(spec);
5365 5429
5366 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 5430 via_smart51_build(spec);
5367 5431
5368 return 1; 5432 return 1;
5369} 5433}
@@ -5384,12 +5448,10 @@ static int patch_vt1716S(struct hda_codec *codec)
5384 int err; 5448 int err;
5385 5449
5386 /* create a codec specific record */ 5450 /* create a codec specific record */
5387 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5451 spec = via_new_spec(codec);
5388 if (spec == NULL) 5452 if (spec == NULL)
5389 return -ENOMEM; 5453 return -ENOMEM;
5390 5454
5391 codec->spec = spec;
5392
5393 /* automatic parse from the BIOS config */ 5455 /* automatic parse from the BIOS config */
5394 err = vt1716S_parse_auto_config(codec); 5456 err = vt1716S_parse_auto_config(codec);
5395 if (err < 0) { 5457 if (err < 0) {
@@ -5719,7 +5781,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec)
5719 spec->input_mux = &spec->private_imux[0]; 5781 spec->input_mux = &spec->private_imux[0];
5720 5782
5721 if (spec->hp_mux) 5783 if (spec->hp_mux)
5722 spec->mixers[spec->num_mixers++] = via_hp_mixer; 5784 via_hp_build(spec);
5723 5785
5724 return 1; 5786 return 1;
5725} 5787}
@@ -5741,12 +5803,10 @@ static int patch_vt2002P(struct hda_codec *codec)
5741 int err; 5803 int err;
5742 5804
5743 /* create a codec specific record */ 5805 /* create a codec specific record */
5744 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5806 spec = via_new_spec(codec);
5745 if (spec == NULL) 5807 if (spec == NULL)
5746 return -ENOMEM; 5808 return -ENOMEM;
5747 5809
5748 codec->spec = spec;
5749
5750 /* automatic parse from the BIOS config */ 5810 /* automatic parse from the BIOS config */
5751 err = vt2002P_parse_auto_config(codec); 5811 err = vt2002P_parse_auto_config(codec);
5752 if (err < 0) { 5812 if (err < 0) {
@@ -6070,7 +6130,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec)
6070 spec->input_mux = &spec->private_imux[0]; 6130 spec->input_mux = &spec->private_imux[0];
6071 6131
6072 if (spec->hp_mux) 6132 if (spec->hp_mux)
6073 spec->mixers[spec->num_mixers++] = via_hp_mixer; 6133 via_hp_build(spec);
6074 6134
6075 return 1; 6135 return 1;
6076} 6136}
@@ -6092,12 +6152,10 @@ static int patch_vt1812(struct hda_codec *codec)
6092 int err; 6152 int err;
6093 6153
6094 /* create a codec specific record */ 6154 /* create a codec specific record */
6095 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 6155 spec = via_new_spec(codec);
6096 if (spec == NULL) 6156 if (spec == NULL)
6097 return -ENOMEM; 6157 return -ENOMEM;
6098 6158
6099 codec->spec = spec;
6100
6101 /* automatic parse from the BIOS config */ 6159 /* automatic parse from the BIOS config */
6102 err = vt1812_parse_auto_config(codec); 6160 err = vt1812_parse_auto_config(codec);
6103 if (err < 0) { 6161 if (err < 0) {