aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_analog.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-07-04 10:34:20 -0400
committerTakashi Iwai <tiwai@suse.de>2013-07-04 12:15:49 -0400
commit36ad45309be840d652394cfb032b592b6a20a3dd (patch)
tree4578c2685c5526b408228d4945e159275b0b3cd2 /sound/pci/hda/patch_analog.c
parentbd450dcc357646cc277c560ab24b35f940efa585 (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.c845
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 */
1721enum {
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
1743static const hda_nid_t ad1988_6stack_dac_nids[4] = {
1744 0x04, 0x06, 0x05, 0x0a
1745};
1746
1747static const hda_nid_t ad1988_3stack_dac_nids[3] = {
1748 0x04, 0x05, 0x0a
1749};
1750
1751/* for AD1988A revision-2, DAC2-4 are swapped */
1752static const hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
1753 0x04, 0x05, 0x0a, 0x06
1754};
1755
1756static const hda_nid_t ad1988_alt_dac_nid[1] = {
1757 0x03
1758};
1759
1760static const hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
1761 0x04, 0x0a, 0x06
1762};
1763
1764static const hda_nid_t ad1988_adc_nids[3] = {
1765 0x08, 0x09, 0x0f
1766};
1767
1768static 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
1776static const hda_nid_t ad1989b_slave_dig_outs[] = {
1777 AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0
1778};
1779
1780static 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
1791static 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 */
1802static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, 1719static 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 */
1834static 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
1843static 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
1852static 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 */
1880static 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
1888static 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
1896static 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 */
1931static 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 */
1963static 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
1985static 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
2000static 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
2022static 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
2069static 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
2082static const struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
2083 HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
2084 { } /* end */
2085};
2086
2087static 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 */
2100static 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
2160static 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
2173static 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
2191static 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
2203static 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 */
2210static 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 */
2223static 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
2233static 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
2243static const struct hda_channel_mode ad1988_3stack_modes[2] = {
2244 { 2, ad1988_3stack_ch2_init },
2245 { 6, ad1988_3stack_ch6_init },
2246};
2247
2248static 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 */
2308static 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};
2314static 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
2323static 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
2376static 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
2387static 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
2397static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol, 1751static 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
2543static int ad1988_parse_auto_config(struct hda_codec *codec) 1897enum {
1898 AD1988_FIXUP_6STACK_DIG,
1899};
1900
1901static 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
1919static const struct hda_model_fixup ad1988_fixup_models[] = {
1920 { .id = AD1988_FIXUP_6STACK_DIG, .name = "6stack-dig" },
1921 {}
1922};
1923
1924static 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
2574static 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
2584static 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
2593static 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