diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-07-04 10:34:20 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-07-04 12:15:49 -0400 |
commit | 36ad45309be840d652394cfb032b592b6a20a3dd (patch) | |
tree | 4578c2685c5526b408228d4945e159275b0b3cd2 /sound/pci/hda/patch_analog.c | |
parent | bd450dcc357646cc277c560ab24b35f940efa585 (diff) |
ALSA: hda - Remove static quirks for AD1988 codecs
For removing static quirks for AD1988 variants, a new fixup defining
the 6stack pinconfig has been added for the buggy BIOS. Other than
that, we can cut off straightforwardly.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_analog.c')
-rw-r--r-- | sound/pci/hda/patch_analog.c | 845 |
1 files changed, 35 insertions, 810 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 4fedd9dfd85a..7777a3a5f59a 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -1715,90 +1715,7 @@ static int patch_ad1981(struct hda_codec *codec) | |||
1715 | * E/F quad mic array | 1715 | * E/F quad mic array |
1716 | */ | 1716 | */ |
1717 | 1717 | ||
1718 | |||
1719 | #ifdef ENABLE_AD_STATIC_QUIRKS | 1718 | #ifdef ENABLE_AD_STATIC_QUIRKS |
1720 | /* models */ | ||
1721 | enum { | ||
1722 | AD1988_AUTO, | ||
1723 | AD1988_6STACK, | ||
1724 | AD1988_6STACK_DIG, | ||
1725 | AD1988_3STACK, | ||
1726 | AD1988_3STACK_DIG, | ||
1727 | AD1988_LAPTOP, | ||
1728 | AD1988_LAPTOP_DIG, | ||
1729 | AD1988_MODEL_LAST, | ||
1730 | }; | ||
1731 | |||
1732 | /* reivision id to check workarounds */ | ||
1733 | #define AD1988A_REV2 0x100200 | ||
1734 | |||
1735 | #define is_rev2(codec) \ | ||
1736 | ((codec)->vendor_id == 0x11d41988 && \ | ||
1737 | (codec)->revision_id == AD1988A_REV2) | ||
1738 | |||
1739 | /* | ||
1740 | * mixers | ||
1741 | */ | ||
1742 | |||
1743 | static const hda_nid_t ad1988_6stack_dac_nids[4] = { | ||
1744 | 0x04, 0x06, 0x05, 0x0a | ||
1745 | }; | ||
1746 | |||
1747 | static const hda_nid_t ad1988_3stack_dac_nids[3] = { | ||
1748 | 0x04, 0x05, 0x0a | ||
1749 | }; | ||
1750 | |||
1751 | /* for AD1988A revision-2, DAC2-4 are swapped */ | ||
1752 | static const hda_nid_t ad1988_6stack_dac_nids_rev2[4] = { | ||
1753 | 0x04, 0x05, 0x0a, 0x06 | ||
1754 | }; | ||
1755 | |||
1756 | static const hda_nid_t ad1988_alt_dac_nid[1] = { | ||
1757 | 0x03 | ||
1758 | }; | ||
1759 | |||
1760 | static const hda_nid_t ad1988_3stack_dac_nids_rev2[3] = { | ||
1761 | 0x04, 0x0a, 0x06 | ||
1762 | }; | ||
1763 | |||
1764 | static const hda_nid_t ad1988_adc_nids[3] = { | ||
1765 | 0x08, 0x09, 0x0f | ||
1766 | }; | ||
1767 | |||
1768 | static const hda_nid_t ad1988_capsrc_nids[3] = { | ||
1769 | 0x0c, 0x0d, 0x0e | ||
1770 | }; | ||
1771 | |||
1772 | #define AD1988_SPDIF_OUT 0x02 | ||
1773 | #define AD1988_SPDIF_OUT_HDMI 0x0b | ||
1774 | #define AD1988_SPDIF_IN 0x07 | ||
1775 | |||
1776 | static const hda_nid_t ad1989b_slave_dig_outs[] = { | ||
1777 | AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0 | ||
1778 | }; | ||
1779 | |||
1780 | static const struct hda_input_mux ad1988_6stack_capture_source = { | ||
1781 | .num_items = 5, | ||
1782 | .items = { | ||
1783 | { "Front Mic", 0x1 }, /* port-B */ | ||
1784 | { "Line", 0x2 }, /* port-C */ | ||
1785 | { "Mic", 0x4 }, /* port-E */ | ||
1786 | { "CD", 0x5 }, | ||
1787 | { "Mix", 0x9 }, | ||
1788 | }, | ||
1789 | }; | ||
1790 | |||
1791 | static const struct hda_input_mux ad1988_laptop_capture_source = { | ||
1792 | .num_items = 3, | ||
1793 | .items = { | ||
1794 | { "Mic/Line", 0x1 }, /* port-B */ | ||
1795 | { "CD", 0x5 }, | ||
1796 | { "Mix", 0x9 }, | ||
1797 | }, | ||
1798 | }; | ||
1799 | |||
1800 | /* | ||
1801 | */ | ||
1802 | static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, | 1719 | static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, |
1803 | struct snd_ctl_elem_info *uinfo) | 1720 | struct snd_ctl_elem_info *uinfo) |
1804 | { | 1721 | { |
@@ -1829,569 +1746,6 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, | |||
1829 | spec->multiout.num_dacs = spec->multiout.max_channels / 2; | 1746 | spec->multiout.num_dacs = spec->multiout.max_channels / 2; |
1830 | return err; | 1747 | return err; |
1831 | } | 1748 | } |
1832 | |||
1833 | /* 6-stack mode */ | ||
1834 | static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = { | ||
1835 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), | ||
1836 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT), | ||
1837 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), | ||
1838 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), | ||
1839 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT), | ||
1840 | { } /* end */ | ||
1841 | }; | ||
1842 | |||
1843 | static const struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = { | ||
1844 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), | ||
1845 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT), | ||
1846 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | ||
1847 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT), | ||
1848 | HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT), | ||
1849 | { } /* end */ | ||
1850 | }; | ||
1851 | |||
1852 | static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = { | ||
1853 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
1854 | HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), | ||
1855 | HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), | ||
1856 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), | ||
1857 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT), | ||
1858 | HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT), | ||
1859 | HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT), | ||
1860 | HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), | ||
1861 | |||
1862 | HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT), | ||
1863 | HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT), | ||
1864 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT), | ||
1865 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT), | ||
1866 | HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT), | ||
1867 | HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT), | ||
1868 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT), | ||
1869 | HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT), | ||
1870 | |||
1871 | HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), | ||
1872 | HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
1873 | |||
1874 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), | ||
1875 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), | ||
1876 | { } /* end */ | ||
1877 | }; | ||
1878 | |||
1879 | /* 3-stack mode */ | ||
1880 | static const struct snd_kcontrol_new ad1988_3stack_mixers1[] = { | ||
1881 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), | ||
1882 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), | ||
1883 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), | ||
1884 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), | ||
1885 | { } /* end */ | ||
1886 | }; | ||
1887 | |||
1888 | static const struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = { | ||
1889 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), | ||
1890 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), | ||
1891 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT), | ||
1892 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT), | ||
1893 | { } /* end */ | ||
1894 | }; | ||
1895 | |||
1896 | static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = { | ||
1897 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
1898 | HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), | ||
1899 | HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT), | ||
1900 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT), | ||
1901 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT), | ||
1902 | HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT), | ||
1903 | HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), | ||
1904 | |||
1905 | HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT), | ||
1906 | HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT), | ||
1907 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT), | ||
1908 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT), | ||
1909 | HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT), | ||
1910 | HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT), | ||
1911 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT), | ||
1912 | HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT), | ||
1913 | |||
1914 | HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), | ||
1915 | HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
1916 | |||
1917 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), | ||
1918 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), | ||
1919 | { | ||
1920 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1921 | .name = "Channel Mode", | ||
1922 | .info = ad198x_ch_mode_info, | ||
1923 | .get = ad198x_ch_mode_get, | ||
1924 | .put = ad198x_ch_mode_put, | ||
1925 | }, | ||
1926 | |||
1927 | { } /* end */ | ||
1928 | }; | ||
1929 | |||
1930 | /* laptop mode */ | ||
1931 | static const struct snd_kcontrol_new ad1988_laptop_mixers[] = { | ||
1932 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
1933 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), | ||
1934 | HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT), | ||
1935 | HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), | ||
1936 | |||
1937 | HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT), | ||
1938 | HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT), | ||
1939 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT), | ||
1940 | HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT), | ||
1941 | HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT), | ||
1942 | HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT), | ||
1943 | |||
1944 | HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), | ||
1945 | HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
1946 | |||
1947 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), | ||
1948 | |||
1949 | { | ||
1950 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1951 | .name = "External Amplifier", | ||
1952 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x12, | ||
1953 | .info = ad198x_eapd_info, | ||
1954 | .get = ad198x_eapd_get, | ||
1955 | .put = ad198x_eapd_put, | ||
1956 | .private_value = 0x12, /* port-D */ | ||
1957 | }, | ||
1958 | |||
1959 | { } /* end */ | ||
1960 | }; | ||
1961 | |||
1962 | /* capture */ | ||
1963 | static const struct snd_kcontrol_new ad1988_capture_mixers[] = { | ||
1964 | HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
1965 | HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), | ||
1966 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), | ||
1967 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), | ||
1968 | HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT), | ||
1969 | HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT), | ||
1970 | { | ||
1971 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1972 | /* The multiple "Capture Source" controls confuse alsamixer | ||
1973 | * So call somewhat different.. | ||
1974 | */ | ||
1975 | /* .name = "Capture Source", */ | ||
1976 | .name = "Input Source", | ||
1977 | .count = 3, | ||
1978 | .info = ad198x_mux_enum_info, | ||
1979 | .get = ad198x_mux_enum_get, | ||
1980 | .put = ad198x_mux_enum_put, | ||
1981 | }, | ||
1982 | { } /* end */ | ||
1983 | }; | ||
1984 | |||
1985 | static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol, | ||
1986 | struct snd_ctl_elem_info *uinfo) | ||
1987 | { | ||
1988 | static const char * const texts[] = { | ||
1989 | "PCM", "ADC1", "ADC2", "ADC3" | ||
1990 | }; | ||
1991 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1992 | uinfo->count = 1; | ||
1993 | uinfo->value.enumerated.items = 4; | ||
1994 | if (uinfo->value.enumerated.item >= 4) | ||
1995 | uinfo->value.enumerated.item = 3; | ||
1996 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1997 | return 0; | ||
1998 | } | ||
1999 | |||
2000 | static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol, | ||
2001 | struct snd_ctl_elem_value *ucontrol) | ||
2002 | { | ||
2003 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2004 | unsigned int sel; | ||
2005 | |||
2006 | sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE, | ||
2007 | AC_AMP_GET_INPUT); | ||
2008 | if (!(sel & 0x80)) | ||
2009 | ucontrol->value.enumerated.item[0] = 0; | ||
2010 | else { | ||
2011 | sel = snd_hda_codec_read(codec, 0x0b, 0, | ||
2012 | AC_VERB_GET_CONNECT_SEL, 0); | ||
2013 | if (sel < 3) | ||
2014 | sel++; | ||
2015 | else | ||
2016 | sel = 0; | ||
2017 | ucontrol->value.enumerated.item[0] = sel; | ||
2018 | } | ||
2019 | return 0; | ||
2020 | } | ||
2021 | |||
2022 | static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol, | ||
2023 | struct snd_ctl_elem_value *ucontrol) | ||
2024 | { | ||
2025 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2026 | unsigned int val, sel; | ||
2027 | int change; | ||
2028 | |||
2029 | val = ucontrol->value.enumerated.item[0]; | ||
2030 | if (val > 3) | ||
2031 | return -EINVAL; | ||
2032 | if (!val) { | ||
2033 | sel = snd_hda_codec_read(codec, 0x1d, 0, | ||
2034 | AC_VERB_GET_AMP_GAIN_MUTE, | ||
2035 | AC_AMP_GET_INPUT); | ||
2036 | change = sel & 0x80; | ||
2037 | if (change) { | ||
2038 | snd_hda_codec_write_cache(codec, 0x1d, 0, | ||
2039 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
2040 | AMP_IN_UNMUTE(0)); | ||
2041 | snd_hda_codec_write_cache(codec, 0x1d, 0, | ||
2042 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
2043 | AMP_IN_MUTE(1)); | ||
2044 | } | ||
2045 | } else { | ||
2046 | sel = snd_hda_codec_read(codec, 0x1d, 0, | ||
2047 | AC_VERB_GET_AMP_GAIN_MUTE, | ||
2048 | AC_AMP_GET_INPUT | 0x01); | ||
2049 | change = sel & 0x80; | ||
2050 | if (change) { | ||
2051 | snd_hda_codec_write_cache(codec, 0x1d, 0, | ||
2052 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
2053 | AMP_IN_MUTE(0)); | ||
2054 | snd_hda_codec_write_cache(codec, 0x1d, 0, | ||
2055 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
2056 | AMP_IN_UNMUTE(1)); | ||
2057 | } | ||
2058 | sel = snd_hda_codec_read(codec, 0x0b, 0, | ||
2059 | AC_VERB_GET_CONNECT_SEL, 0) + 1; | ||
2060 | change |= sel != val; | ||
2061 | if (change) | ||
2062 | snd_hda_codec_write_cache(codec, 0x0b, 0, | ||
2063 | AC_VERB_SET_CONNECT_SEL, | ||
2064 | val - 1); | ||
2065 | } | ||
2066 | return change; | ||
2067 | } | ||
2068 | |||
2069 | static const struct snd_kcontrol_new ad1988_spdif_out_mixers[] = { | ||
2070 | HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), | ||
2071 | { | ||
2072 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2073 | .name = "IEC958 Playback Source", | ||
2074 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b, | ||
2075 | .info = ad1988_spdif_playback_source_info, | ||
2076 | .get = ad1988_spdif_playback_source_get, | ||
2077 | .put = ad1988_spdif_playback_source_put, | ||
2078 | }, | ||
2079 | { } /* end */ | ||
2080 | }; | ||
2081 | |||
2082 | static const struct snd_kcontrol_new ad1988_spdif_in_mixers[] = { | ||
2083 | HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT), | ||
2084 | { } /* end */ | ||
2085 | }; | ||
2086 | |||
2087 | static const struct snd_kcontrol_new ad1989_spdif_out_mixers[] = { | ||
2088 | HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), | ||
2089 | HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT), | ||
2090 | { } /* end */ | ||
2091 | }; | ||
2092 | |||
2093 | /* | ||
2094 | * initialization verbs | ||
2095 | */ | ||
2096 | |||
2097 | /* | ||
2098 | * for 6-stack (+dig) | ||
2099 | */ | ||
2100 | static const struct hda_verb ad1988_6stack_init_verbs[] = { | ||
2101 | /* Front, Surround, CLFE, side DAC; unmute as default */ | ||
2102 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2103 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2104 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2105 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2106 | /* Port-A front headphon path */ | ||
2107 | {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ | ||
2108 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2109 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2110 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2111 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
2112 | /* Port-D line-out path */ | ||
2113 | {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2114 | {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2115 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2116 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2117 | /* Port-F surround path */ | ||
2118 | {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2119 | {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2120 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2121 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2122 | /* Port-G CLFE path */ | ||
2123 | {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2124 | {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2125 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2126 | {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2127 | /* Port-H side path */ | ||
2128 | {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2129 | {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2130 | {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2131 | {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2132 | /* Mono out path */ | ||
2133 | {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */ | ||
2134 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2135 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2136 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2137 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */ | ||
2138 | /* Port-B front mic-in path */ | ||
2139 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2140 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
2141 | {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
2142 | /* Port-C line-in path */ | ||
2143 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2144 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
2145 | {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
2146 | {0x33, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
2147 | /* Port-E mic-in path */ | ||
2148 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2149 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
2150 | {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
2151 | {0x34, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
2152 | /* Analog CD Input */ | ||
2153 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
2154 | /* Analog Mix output amp */ | ||
2155 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ | ||
2156 | |||
2157 | { } | ||
2158 | }; | ||
2159 | |||
2160 | static const struct hda_verb ad1988_6stack_fp_init_verbs[] = { | ||
2161 | /* Headphone; unmute as default */ | ||
2162 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2163 | /* Port-A front headphon path */ | ||
2164 | {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ | ||
2165 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2166 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2167 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2168 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
2169 | |||
2170 | { } | ||
2171 | }; | ||
2172 | |||
2173 | static const struct hda_verb ad1988_capture_init_verbs[] = { | ||
2174 | /* mute analog mix */ | ||
2175 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2176 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2177 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
2178 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
2179 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
2180 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, | ||
2181 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, | ||
2182 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, | ||
2183 | /* select ADCs - front-mic */ | ||
2184 | {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
2185 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
2186 | {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
2187 | |||
2188 | { } | ||
2189 | }; | ||
2190 | |||
2191 | static const struct hda_verb ad1988_spdif_init_verbs[] = { | ||
2192 | /* SPDIF out sel */ | ||
2193 | {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ | ||
2194 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */ | ||
2195 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
2196 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2197 | /* SPDIF out pin */ | ||
2198 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ | ||
2199 | |||
2200 | { } | ||
2201 | }; | ||
2202 | |||
2203 | static const struct hda_verb ad1988_spdif_in_init_verbs[] = { | ||
2204 | /* unmute SPDIF input pin */ | ||
2205 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
2206 | { } | ||
2207 | }; | ||
2208 | |||
2209 | /* AD1989 has no ADC -> SPDIF route */ | ||
2210 | static const struct hda_verb ad1989_spdif_init_verbs[] = { | ||
2211 | /* SPDIF-1 out pin */ | ||
2212 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
2213 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ | ||
2214 | /* SPDIF-2/HDMI out pin */ | ||
2215 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
2216 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ | ||
2217 | { } | ||
2218 | }; | ||
2219 | |||
2220 | /* | ||
2221 | * verbs for 3stack (+dig) | ||
2222 | */ | ||
2223 | static const struct hda_verb ad1988_3stack_ch2_init[] = { | ||
2224 | /* set port-C to line-in */ | ||
2225 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
2226 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
2227 | /* set port-E to mic-in */ | ||
2228 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
2229 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
2230 | { } /* end */ | ||
2231 | }; | ||
2232 | |||
2233 | static const struct hda_verb ad1988_3stack_ch6_init[] = { | ||
2234 | /* set port-C to surround out */ | ||
2235 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
2236 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
2237 | /* set port-E to CLFE out */ | ||
2238 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
2239 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
2240 | { } /* end */ | ||
2241 | }; | ||
2242 | |||
2243 | static const struct hda_channel_mode ad1988_3stack_modes[2] = { | ||
2244 | { 2, ad1988_3stack_ch2_init }, | ||
2245 | { 6, ad1988_3stack_ch6_init }, | ||
2246 | }; | ||
2247 | |||
2248 | static const struct hda_verb ad1988_3stack_init_verbs[] = { | ||
2249 | /* Front, Surround, CLFE, side DAC; unmute as default */ | ||
2250 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2251 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2252 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2253 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2254 | /* Port-A front headphon path */ | ||
2255 | {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ | ||
2256 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2257 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2258 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2259 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
2260 | /* Port-D line-out path */ | ||
2261 | {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2262 | {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2263 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2264 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2265 | /* Mono out path */ | ||
2266 | {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */ | ||
2267 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2268 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2269 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2270 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */ | ||
2271 | /* Port-B front mic-in path */ | ||
2272 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2273 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
2274 | {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
2275 | /* Port-C line-in/surround path - 6ch mode as default */ | ||
2276 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2277 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2278 | {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
2279 | {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */ | ||
2280 | {0x33, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
2281 | /* Port-E mic-in/CLFE path - 6ch mode as default */ | ||
2282 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2283 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2284 | {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
2285 | {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */ | ||
2286 | {0x34, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
2287 | /* mute analog mix */ | ||
2288 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2289 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2290 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
2291 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
2292 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
2293 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, | ||
2294 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, | ||
2295 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, | ||
2296 | /* select ADCs - front-mic */ | ||
2297 | {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
2298 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
2299 | {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
2300 | /* Analog Mix output amp */ | ||
2301 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ | ||
2302 | { } | ||
2303 | }; | ||
2304 | |||
2305 | /* | ||
2306 | * verbs for laptop mode (+dig) | ||
2307 | */ | ||
2308 | static const struct hda_verb ad1988_laptop_hp_on[] = { | ||
2309 | /* unmute port-A and mute port-D */ | ||
2310 | { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
2311 | { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
2312 | { } /* end */ | ||
2313 | }; | ||
2314 | static const struct hda_verb ad1988_laptop_hp_off[] = { | ||
2315 | /* mute port-A and unmute port-D */ | ||
2316 | { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
2317 | { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
2318 | { } /* end */ | ||
2319 | }; | ||
2320 | |||
2321 | #define AD1988_HP_EVENT 0x01 | ||
2322 | |||
2323 | static const struct hda_verb ad1988_laptop_init_verbs[] = { | ||
2324 | /* Front, Surround, CLFE, side DAC; unmute as default */ | ||
2325 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2326 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2327 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2328 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2329 | /* Port-A front headphon path */ | ||
2330 | {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ | ||
2331 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2332 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2333 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2334 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
2335 | /* unsolicited event for pin-sense */ | ||
2336 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT }, | ||
2337 | /* Port-D line-out path + EAPD */ | ||
2338 | {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2339 | {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2340 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2341 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2342 | {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */ | ||
2343 | /* Mono out path */ | ||
2344 | {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */ | ||
2345 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2346 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2347 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2348 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */ | ||
2349 | /* Port-B mic-in path */ | ||
2350 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2351 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
2352 | {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
2353 | /* Port-C docking station - try to output */ | ||
2354 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2355 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2356 | {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
2357 | {0x33, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
2358 | /* mute analog mix */ | ||
2359 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2360 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2361 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
2362 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
2363 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
2364 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, | ||
2365 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, | ||
2366 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, | ||
2367 | /* select ADCs - mic */ | ||
2368 | {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
2369 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
2370 | {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
2371 | /* Analog Mix output amp */ | ||
2372 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ | ||
2373 | { } | ||
2374 | }; | ||
2375 | |||
2376 | static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res) | ||
2377 | { | ||
2378 | if ((res >> 26) != AD1988_HP_EVENT) | ||
2379 | return; | ||
2380 | if (snd_hda_jack_detect(codec, 0x11)) | ||
2381 | snd_hda_sequence_write(codec, ad1988_laptop_hp_on); | ||
2382 | else | ||
2383 | snd_hda_sequence_write(codec, ad1988_laptop_hp_off); | ||
2384 | } | ||
2385 | |||
2386 | #ifdef CONFIG_PM | ||
2387 | static const struct hda_amp_list ad1988_loopbacks[] = { | ||
2388 | { 0x20, HDA_INPUT, 0 }, /* Front Mic */ | ||
2389 | { 0x20, HDA_INPUT, 1 }, /* Line */ | ||
2390 | { 0x20, HDA_INPUT, 4 }, /* Mic */ | ||
2391 | { 0x20, HDA_INPUT, 6 }, /* CD */ | ||
2392 | { } /* end */ | ||
2393 | }; | ||
2394 | #endif | ||
2395 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | 1749 | #endif /* ENABLE_AD_STATIC_QUIRKS */ |
2396 | 1750 | ||
2397 | static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol, | 1751 | static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol, |
@@ -2540,7 +1894,34 @@ static int ad1988_add_spdif_mux_ctl(struct hda_codec *codec) | |||
2540 | /* | 1894 | /* |
2541 | */ | 1895 | */ |
2542 | 1896 | ||
2543 | static int ad1988_parse_auto_config(struct hda_codec *codec) | 1897 | enum { |
1898 | AD1988_FIXUP_6STACK_DIG, | ||
1899 | }; | ||
1900 | |||
1901 | static const struct hda_fixup ad1988_fixups[] = { | ||
1902 | [AD1988_FIXUP_6STACK_DIG] = { | ||
1903 | .type = HDA_FIXUP_PINS, | ||
1904 | .v.pins = (const struct hda_pintbl[]) { | ||
1905 | { 0x11, 0x02214130 }, /* front-hp */ | ||
1906 | { 0x12, 0x01014010 }, /* line-out */ | ||
1907 | { 0x14, 0x02a19122 }, /* front-mic */ | ||
1908 | { 0x15, 0x01813021 }, /* line-in */ | ||
1909 | { 0x16, 0x01011012 }, /* line-out */ | ||
1910 | { 0x17, 0x01a19020 }, /* mic */ | ||
1911 | { 0x1b, 0x0145f1f0 }, /* SPDIF */ | ||
1912 | { 0x24, 0x01016011 }, /* line-out */ | ||
1913 | { 0x25, 0x01012013 }, /* line-out */ | ||
1914 | { } | ||
1915 | } | ||
1916 | }, | ||
1917 | }; | ||
1918 | |||
1919 | static const struct hda_model_fixup ad1988_fixup_models[] = { | ||
1920 | { .id = AD1988_FIXUP_6STACK_DIG, .name = "6stack-dig" }, | ||
1921 | {} | ||
1922 | }; | ||
1923 | |||
1924 | static int patch_ad1988(struct hda_codec *codec) | ||
2544 | { | 1925 | { |
2545 | struct ad198x_spec *spec; | 1926 | struct ad198x_spec *spec; |
2546 | int err; | 1927 | int err; |
@@ -2554,12 +1935,19 @@ static int ad1988_parse_auto_config(struct hda_codec *codec) | |||
2554 | spec->gen.mixer_merge_nid = 0x21; | 1935 | spec->gen.mixer_merge_nid = 0x21; |
2555 | spec->gen.beep_nid = 0x10; | 1936 | spec->gen.beep_nid = 0x10; |
2556 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | 1937 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); |
1938 | |||
1939 | snd_hda_pick_fixup(codec, ad1988_fixup_models, NULL, ad1988_fixups); | ||
1940 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | ||
1941 | |||
2557 | err = ad198x_parse_auto_config(codec); | 1942 | err = ad198x_parse_auto_config(codec); |
2558 | if (err < 0) | 1943 | if (err < 0) |
2559 | goto error; | 1944 | goto error; |
2560 | err = ad1988_add_spdif_mux_ctl(codec); | 1945 | err = ad1988_add_spdif_mux_ctl(codec); |
2561 | if (err < 0) | 1946 | if (err < 0) |
2562 | goto error; | 1947 | goto error; |
1948 | |||
1949 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | ||
1950 | |||
2563 | return 0; | 1951 | return 0; |
2564 | 1952 | ||
2565 | error: | 1953 | error: |
@@ -2567,169 +1955,6 @@ static int ad1988_parse_auto_config(struct hda_codec *codec) | |||
2567 | return err; | 1955 | return err; |
2568 | } | 1956 | } |
2569 | 1957 | ||
2570 | /* | ||
2571 | */ | ||
2572 | |||
2573 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
2574 | static const char * const ad1988_models[AD1988_MODEL_LAST] = { | ||
2575 | [AD1988_6STACK] = "6stack", | ||
2576 | [AD1988_6STACK_DIG] = "6stack-dig", | ||
2577 | [AD1988_3STACK] = "3stack", | ||
2578 | [AD1988_3STACK_DIG] = "3stack-dig", | ||
2579 | [AD1988_LAPTOP] = "laptop", | ||
2580 | [AD1988_LAPTOP_DIG] = "laptop-dig", | ||
2581 | [AD1988_AUTO] = "auto", | ||
2582 | }; | ||
2583 | |||
2584 | static const struct snd_pci_quirk ad1988_cfg_tbl[] = { | ||
2585 | SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG), | ||
2586 | SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG), | ||
2587 | SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG), | ||
2588 | SND_PCI_QUIRK(0x1043, 0x82c0, "Asus M3N-HT Deluxe", AD1988_6STACK_DIG), | ||
2589 | SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG), | ||
2590 | {} | ||
2591 | }; | ||
2592 | |||
2593 | static int patch_ad1988(struct hda_codec *codec) | ||
2594 | { | ||
2595 | struct ad198x_spec *spec; | ||
2596 | int err, board_config; | ||
2597 | |||
2598 | board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST, | ||
2599 | ad1988_models, ad1988_cfg_tbl); | ||
2600 | if (board_config < 0) { | ||
2601 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
2602 | codec->chip_name); | ||
2603 | board_config = AD1988_AUTO; | ||
2604 | } | ||
2605 | |||
2606 | if (board_config == AD1988_AUTO) | ||
2607 | return ad1988_parse_auto_config(codec); | ||
2608 | |||
2609 | err = alloc_ad_spec(codec); | ||
2610 | if (err < 0) | ||
2611 | return err; | ||
2612 | spec = codec->spec; | ||
2613 | |||
2614 | if (is_rev2(codec)) | ||
2615 | snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n"); | ||
2616 | |||
2617 | err = snd_hda_attach_beep_device(codec, 0x10); | ||
2618 | if (err < 0) { | ||
2619 | ad198x_free(codec); | ||
2620 | return err; | ||
2621 | } | ||
2622 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | ||
2623 | |||
2624 | if (!spec->multiout.hp_nid) | ||
2625 | spec->multiout.hp_nid = ad1988_alt_dac_nid[0]; | ||
2626 | switch (board_config) { | ||
2627 | case AD1988_6STACK: | ||
2628 | case AD1988_6STACK_DIG: | ||
2629 | spec->multiout.max_channels = 8; | ||
2630 | spec->multiout.num_dacs = 4; | ||
2631 | if (is_rev2(codec)) | ||
2632 | spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2; | ||
2633 | else | ||
2634 | spec->multiout.dac_nids = ad1988_6stack_dac_nids; | ||
2635 | spec->input_mux = &ad1988_6stack_capture_source; | ||
2636 | spec->num_mixers = 2; | ||
2637 | if (is_rev2(codec)) | ||
2638 | spec->mixers[0] = ad1988_6stack_mixers1_rev2; | ||
2639 | else | ||
2640 | spec->mixers[0] = ad1988_6stack_mixers1; | ||
2641 | spec->mixers[1] = ad1988_6stack_mixers2; | ||
2642 | spec->num_init_verbs = 1; | ||
2643 | spec->init_verbs[0] = ad1988_6stack_init_verbs; | ||
2644 | if (board_config == AD1988_6STACK_DIG) { | ||
2645 | spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; | ||
2646 | spec->dig_in_nid = AD1988_SPDIF_IN; | ||
2647 | } | ||
2648 | break; | ||
2649 | case AD1988_3STACK: | ||
2650 | case AD1988_3STACK_DIG: | ||
2651 | spec->multiout.max_channels = 6; | ||
2652 | spec->multiout.num_dacs = 3; | ||
2653 | if (is_rev2(codec)) | ||
2654 | spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2; | ||
2655 | else | ||
2656 | spec->multiout.dac_nids = ad1988_3stack_dac_nids; | ||
2657 | spec->input_mux = &ad1988_6stack_capture_source; | ||
2658 | spec->channel_mode = ad1988_3stack_modes; | ||
2659 | spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes); | ||
2660 | spec->num_mixers = 2; | ||
2661 | if (is_rev2(codec)) | ||
2662 | spec->mixers[0] = ad1988_3stack_mixers1_rev2; | ||
2663 | else | ||
2664 | spec->mixers[0] = ad1988_3stack_mixers1; | ||
2665 | spec->mixers[1] = ad1988_3stack_mixers2; | ||
2666 | spec->num_init_verbs = 1; | ||
2667 | spec->init_verbs[0] = ad1988_3stack_init_verbs; | ||
2668 | if (board_config == AD1988_3STACK_DIG) | ||
2669 | spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; | ||
2670 | break; | ||
2671 | case AD1988_LAPTOP: | ||
2672 | case AD1988_LAPTOP_DIG: | ||
2673 | spec->multiout.max_channels = 2; | ||
2674 | spec->multiout.num_dacs = 1; | ||
2675 | spec->multiout.dac_nids = ad1988_3stack_dac_nids; | ||
2676 | spec->input_mux = &ad1988_laptop_capture_source; | ||
2677 | spec->num_mixers = 1; | ||
2678 | spec->mixers[0] = ad1988_laptop_mixers; | ||
2679 | codec->inv_eapd = 1; /* inverted EAPD */ | ||
2680 | spec->num_init_verbs = 1; | ||
2681 | spec->init_verbs[0] = ad1988_laptop_init_verbs; | ||
2682 | if (board_config == AD1988_LAPTOP_DIG) | ||
2683 | spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; | ||
2684 | break; | ||
2685 | } | ||
2686 | |||
2687 | spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids); | ||
2688 | spec->adc_nids = ad1988_adc_nids; | ||
2689 | spec->capsrc_nids = ad1988_capsrc_nids; | ||
2690 | spec->mixers[spec->num_mixers++] = ad1988_capture_mixers; | ||
2691 | spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs; | ||
2692 | if (spec->multiout.dig_out_nid) { | ||
2693 | if (codec->vendor_id >= 0x11d4989a) { | ||
2694 | spec->mixers[spec->num_mixers++] = | ||
2695 | ad1989_spdif_out_mixers; | ||
2696 | spec->init_verbs[spec->num_init_verbs++] = | ||
2697 | ad1989_spdif_init_verbs; | ||
2698 | codec->slave_dig_outs = ad1989b_slave_dig_outs; | ||
2699 | } else { | ||
2700 | spec->mixers[spec->num_mixers++] = | ||
2701 | ad1988_spdif_out_mixers; | ||
2702 | spec->init_verbs[spec->num_init_verbs++] = | ||
2703 | ad1988_spdif_init_verbs; | ||
2704 | } | ||
2705 | } | ||
2706 | if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) { | ||
2707 | spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers; | ||
2708 | spec->init_verbs[spec->num_init_verbs++] = | ||
2709 | ad1988_spdif_in_init_verbs; | ||
2710 | } | ||
2711 | |||
2712 | codec->patch_ops = ad198x_patch_ops; | ||
2713 | switch (board_config) { | ||
2714 | case AD1988_LAPTOP: | ||
2715 | case AD1988_LAPTOP_DIG: | ||
2716 | codec->patch_ops.unsol_event = ad1988_laptop_unsol_event; | ||
2717 | break; | ||
2718 | } | ||
2719 | #ifdef CONFIG_PM | ||
2720 | spec->loopback.amplist = ad1988_loopbacks; | ||
2721 | #endif | ||
2722 | spec->vmaster_nid = 0x04; | ||
2723 | |||
2724 | codec->no_trigger_sense = 1; | ||
2725 | codec->no_sticky_stream = 1; | ||
2726 | |||
2727 | return 0; | ||
2728 | } | ||
2729 | #else /* ENABLE_AD_STATIC_QUIRKS */ | ||
2730 | #define patch_ad1988 ad1988_parse_auto_config | ||
2731 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
2732 | |||
2733 | 1958 | ||
2734 | /* | 1959 | /* |
2735 | * AD1884 / AD1984 | 1960 | * AD1884 / AD1984 |