aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ac97
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/ac97')
-rw-r--r--sound/pci/ac97/ac97_patch.c103
1 files changed, 92 insertions, 11 deletions
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 5f69b9c9f1b3..bd27531a0f0e 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -1632,13 +1632,16 @@ int patch_ad1886(struct snd_ac97 * ac97)
1632#define AC97_AD198X_MBC_10 0x0001 /* +10dB */ 1632#define AC97_AD198X_MBC_10 0x0001 /* +10dB */
1633#define AC97_AD198X_MBC_30 0x0002 /* +30dB */ 1633#define AC97_AD198X_MBC_30 0x0002 /* +30dB */
1634#define AC97_AD198X_VREFD 0x0004 /* VREF high-Z */ 1634#define AC97_AD198X_VREFD 0x0004 /* VREF high-Z */
1635#define AC97_AD198X_VREFH 0x0008 /* 2.25V, 3.7V */ 1635#define AC97_AD198X_VREFH 0x0008 /* 0=2.25V, 1=3.7V */
1636#define AC97_AD198X_VREF_0 0x000c /* 0V */ 1636#define AC97_AD198X_VREF_0 0x000c /* 0V (AD1985 only) */
1637#define AC97_AD198X_VREF_MASK (AC97_AD198X_VREFH | AC97_AD198X_VREFD)
1638#define AC97_AD198X_VREF_SHIFT 2
1637#define AC97_AD198X_SRU 0x0010 /* sample rate unlock */ 1639#define AC97_AD198X_SRU 0x0010 /* sample rate unlock */
1638#define AC97_AD198X_LOSEL 0x0020 /* LINE_OUT amplifiers input select */ 1640#define AC97_AD198X_LOSEL 0x0020 /* LINE_OUT amplifiers input select */
1639#define AC97_AD198X_2MIC 0x0040 /* 2-channel mic select */ 1641#define AC97_AD198X_2MIC 0x0040 /* 2-channel mic select */
1640#define AC97_AD198X_SPRD 0x0080 /* SPREAD enable */ 1642#define AC97_AD198X_SPRD 0x0080 /* SPREAD enable */
1641#define AC97_AD198X_DMIX0 0x0100 /* downmix mode: 0 = 6-to-4, 1 = 6-to-2 downmix */ 1643#define AC97_AD198X_DMIX0 0x0100 /* downmix mode: */
1644 /* 0 = 6-to-4, 1 = 6-to-2 downmix */
1642#define AC97_AD198X_DMIX1 0x0200 /* downmix mode: 1 = enabled */ 1645#define AC97_AD198X_DMIX1 0x0200 /* downmix mode: 1 = enabled */
1643#define AC97_AD198X_HPSEL 0x0400 /* headphone amplifier input select */ 1646#define AC97_AD198X_HPSEL 0x0400 /* headphone amplifier input select */
1644#define AC97_AD198X_CLDIS 0x0800 /* center/lfe disable */ 1647#define AC97_AD198X_CLDIS 0x0800 /* center/lfe disable */
@@ -1969,8 +1972,80 @@ int patch_ad1980(struct snd_ac97 * ac97)
1969 return 0; 1972 return 0;
1970} 1973}
1971 1974
1975static int snd_ac97_ad1985_vrefout_info(struct snd_kcontrol *kcontrol,
1976 struct snd_ctl_elem_info *uinfo)
1977{
1978 static char *texts[4] = {"High-Z", "3.7 V", "2.25 V", "0 V"};
1979
1980 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1981 uinfo->count = 1;
1982 uinfo->value.enumerated.items = 4;
1983 if (uinfo->value.enumerated.item > 3)
1984 uinfo->value.enumerated.item = 3;
1985 strcpy(uinfo->value.enumerated.name,
1986 texts[uinfo->value.enumerated.item]);
1987 return 0;
1988}
1989
1990static int snd_ac97_ad1985_vrefout_get(struct snd_kcontrol *kcontrol,
1991 struct snd_ctl_elem_value *ucontrol)
1992{
1993 static const int reg2ctrl[4] = {2, 0, 1, 3};
1994 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1995 unsigned short val;
1996 val = (ac97->regs[AC97_AD_MISC] & AC97_AD198X_VREF_MASK)
1997 >> AC97_AD198X_VREF_SHIFT;
1998 ucontrol->value.enumerated.item[0] = reg2ctrl[val];
1999 return 0;
2000}
2001
2002static int snd_ac97_ad1985_vrefout_put(struct snd_kcontrol *kcontrol,
2003 struct snd_ctl_elem_value *ucontrol)
2004{
2005 static const int ctrl2reg[4] = {1, 2, 0, 3};
2006 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2007 unsigned short val;
2008
2009 if (ucontrol->value.enumerated.item[0] > 3
2010 || ucontrol->value.enumerated.item[0] < 0)
2011 return -EINVAL;
2012 val = ctrl2reg[ucontrol->value.enumerated.item[0]]
2013 << AC97_AD198X_VREF_SHIFT;
2014 return snd_ac97_update_bits(ac97, AC97_AD_MISC,
2015 AC97_AD198X_VREF_MASK, val);
2016}
2017
1972static const struct snd_kcontrol_new snd_ac97_ad1985_controls[] = { 2018static const struct snd_kcontrol_new snd_ac97_ad1985_controls[] = {
1973 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0) 2019 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0),
2020 {
2021 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2022 .name = "Exchange Front/Surround",
2023 .info = snd_ac97_ad1888_lohpsel_info,
2024 .get = snd_ac97_ad1888_lohpsel_get,
2025 .put = snd_ac97_ad1888_lohpsel_put
2026 },
2027 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 12, 1, 1),
2028 AC97_SINGLE("Spread Front to Surround and Center/LFE",
2029 AC97_AD_MISC, 7, 1, 0),
2030 {
2031 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2032 .name = "Downmix",
2033 .info = snd_ac97_ad1888_downmix_info,
2034 .get = snd_ac97_ad1888_downmix_get,
2035 .put = snd_ac97_ad1888_downmix_put
2036 },
2037 {
2038 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2039 .name = "V_REFOUT",
2040 .info = snd_ac97_ad1985_vrefout_info,
2041 .get = snd_ac97_ad1985_vrefout_get,
2042 .put = snd_ac97_ad1985_vrefout_put
2043 },
2044 AC97_SURROUND_JACK_MODE_CTL,
2045 AC97_CHANNEL_MODE_CTL,
2046
2047 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
2048 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
1974}; 2049};
1975 2050
1976static void ad1985_update_jacks(struct snd_ac97 *ac97) 2051static void ad1985_update_jacks(struct snd_ac97 *ac97)
@@ -1984,9 +2059,16 @@ static int patch_ad1985_specific(struct snd_ac97 *ac97)
1984{ 2059{
1985 int err; 2060 int err;
1986 2061
1987 if ((err = patch_ad1980_specific(ac97)) < 0) 2062 /* rename 0x04 as "Master" and 0x02 as "Master Surround" */
2063 snd_ac97_rename_vol_ctl(ac97, "Master Playback",
2064 "Master Surround Playback");
2065 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
2066
2067 if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
1988 return err; 2068 return err;
1989 return patch_build_controls(ac97, snd_ac97_ad1985_controls, ARRAY_SIZE(snd_ac97_ad1985_controls)); 2069
2070 return patch_build_controls(ac97, snd_ac97_ad1985_controls,
2071 ARRAY_SIZE(snd_ac97_ad1985_controls));
1990} 2072}
1991 2073
1992static struct snd_ac97_build_ops patch_ad1985_build_ops = { 2074static struct snd_ac97_build_ops patch_ad1985_build_ops = {
@@ -2006,19 +2088,18 @@ int patch_ad1985(struct snd_ac97 * ac97)
2006 ac97->build_ops = &patch_ad1985_build_ops; 2088 ac97->build_ops = &patch_ad1985_build_ops;
2007 misc = snd_ac97_read(ac97, AC97_AD_MISC); 2089 misc = snd_ac97_read(ac97, AC97_AD_MISC);
2008 /* switch front/surround line-out/hp-out */ 2090 /* switch front/surround line-out/hp-out */
2009 /* center/LFE, mic in 3.75V mode */
2010 /* AD-compatible mode */ 2091 /* AD-compatible mode */
2011 /* Stereo mutes enabled */ 2092 /* Stereo mutes enabled */
2012 /* in accordance with ADI driver: misc | 0x5c28 */
2013 snd_ac97_write_cache(ac97, AC97_AD_MISC, misc | 2093 snd_ac97_write_cache(ac97, AC97_AD_MISC, misc |
2014 AC97_AD198X_VREFH |
2015 AC97_AD198X_LOSEL | 2094 AC97_AD198X_LOSEL |
2016 AC97_AD198X_HPSEL | 2095 AC97_AD198X_HPSEL |
2017 AC97_AD198X_CLDIS |
2018 AC97_AD198X_LODIS |
2019 AC97_AD198X_MSPLT | 2096 AC97_AD198X_MSPLT |
2020 AC97_AD198X_AC97NC); 2097 AC97_AD198X_AC97NC);
2021 ac97->flags |= AC97_STEREO_MUTES; 2098 ac97->flags |= AC97_STEREO_MUTES;
2099
2100 /* update current jack configuration */
2101 ad1985_update_jacks(ac97);
2102
2022 /* on AD1985 rev. 3, AC'97 revision bits are zero */ 2103 /* on AD1985 rev. 3, AC'97 revision bits are zero */
2023 ac97->ext_id = (ac97->ext_id & ~AC97_EI_REV_MASK) | AC97_EI_REV_23; 2104 ac97->ext_id = (ac97->ext_id & ~AC97_EI_REV_MASK) | AC97_EI_REV_23;
2024 return 0; 2105 return 0;