diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/ac97/ac97_patch.c | 103 |
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 | ||
1975 | static 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 | |||
1990 | static 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 | |||
2002 | static 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 | |||
1972 | static const struct snd_kcontrol_new snd_ac97_ad1985_controls[] = { | 2018 | static 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 | ||
1976 | static void ad1985_update_jacks(struct snd_ac97 *ac97) | 2051 | static 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 | ||
1992 | static struct snd_ac97_build_ops patch_ad1985_build_ops = { | 2074 | static 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; |