diff options
| author | Randy Cushman <rcushman_linux@earthlink.net> | 2006-12-22 06:44:25 -0500 |
|---|---|---|
| committer | Jaroslav Kysela <perex@suse.cz> | 2007-02-09 03:02:46 -0500 |
| commit | 67e9f4b68c9d1820132c559c0f9b296dafdf631e (patch) | |
| tree | 4b51b76112e0e218774970d0a2d3c522252f7128 /sound/pci/ac97 | |
| parent | 6428ea1b733e4795209ff272be32732ec152594a (diff) | |
[ALSA] ac97 - fix various issues with AD1986/AD1986A support
Previously, ac97_codec.c was coded to support AD1986 and AD1986A
CODECs using code written for the AD1985 CODEC. This allowed the
LINE_OUT and HEADPHONE jacks to function properly, however register
differences between the CODECs prevented line and microphone inputs
from functioning.
Specifically, this patch fixes issues with the following mixer
controls: 'V_REFOUT', 'Spread Front to Surround and Center/LFE',
'Exchange Front/Surround', 'Surround Jack Mode', and 'Channel Mode'.
This patch removes the undocumented AD1888 control
'High Pass Filter Enable' and adds the new control
'Exchange Mic/Line In'.
Signed-off-by: Randy Cushman <rcushman_linux@earthlink.net>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/ac97')
| -rw-r--r-- | sound/pci/ac97/ac97_codec.c | 2 | ||||
| -rw-r--r-- | sound/pci/ac97/ac97_patch.c | 367 | ||||
| -rw-r--r-- | sound/pci/ac97/ac97_patch.h | 1 |
3 files changed, 368 insertions, 2 deletions
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 9da4977c0a..bd8cfdcfbd 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
| @@ -111,7 +111,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { | |||
| 111 | { 0x41445372, 0xffffffff, "AD1981A", patch_ad1981a, NULL }, | 111 | { 0x41445372, 0xffffffff, "AD1981A", patch_ad1981a, NULL }, |
| 112 | { 0x41445374, 0xffffffff, "AD1981B", patch_ad1981b, NULL }, | 112 | { 0x41445374, 0xffffffff, "AD1981B", patch_ad1981b, NULL }, |
| 113 | { 0x41445375, 0xffffffff, "AD1985", patch_ad1985, NULL }, | 113 | { 0x41445375, 0xffffffff, "AD1985", patch_ad1985, NULL }, |
| 114 | { 0x41445378, 0xffffffff, "AD1986", patch_ad1985, NULL }, | 114 | { 0x41445378, 0xffffffff, "AD1986", patch_ad1986, NULL }, |
| 115 | { 0x414c4300, 0xffffff00, "ALC100,100P", NULL, NULL }, | 115 | { 0x414c4300, 0xffffff00, "ALC100,100P", NULL, NULL }, |
| 116 | { 0x414c4710, 0xfffffff0, "ALC200,200P", NULL, NULL }, | 116 | { 0x414c4710, 0xfffffff0, "ALC200,200P", NULL, NULL }, |
| 117 | { 0x414c4721, 0xffffffff, "ALC650D", NULL, NULL }, /* already patched */ | 117 | { 0x414c4721, 0xffffffff, "ALC650D", NULL, NULL }, /* already patched */ |
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index bd27531a0f..f5b4b44bbd 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
| @@ -1626,7 +1626,7 @@ int patch_ad1886(struct snd_ac97 * ac97) | |||
| 1626 | return 0; | 1626 | return 0; |
| 1627 | } | 1627 | } |
| 1628 | 1628 | ||
| 1629 | /* MISC bits */ | 1629 | /* MISC bits (AD1888/AD1980/AD1985 register 0x76) */ |
| 1630 | #define AC97_AD198X_MBC 0x0003 /* mic boost */ | 1630 | #define AC97_AD198X_MBC 0x0003 /* mic boost */ |
| 1631 | #define AC97_AD198X_MBC_20 0x0000 /* +20dB */ | 1631 | #define AC97_AD198X_MBC_20 0x0000 /* +20dB */ |
| 1632 | #define AC97_AD198X_MBC_10 0x0001 /* +10dB */ | 1632 | #define AC97_AD198X_MBC_10 0x0001 /* +10dB */ |
| @@ -1650,6 +1650,83 @@ int patch_ad1886(struct snd_ac97 * ac97) | |||
| 1650 | #define AC97_AD198X_AC97NC 0x4000 /* AC97 no compatible mode */ | 1650 | #define AC97_AD198X_AC97NC 0x4000 /* AC97 no compatible mode */ |
| 1651 | #define AC97_AD198X_DACZ 0x8000 /* DAC zero-fill mode */ | 1651 | #define AC97_AD198X_DACZ 0x8000 /* DAC zero-fill mode */ |
| 1652 | 1652 | ||
| 1653 | /* MISC 1 bits (AD1986 register 0x76) */ | ||
| 1654 | #define AC97_AD1986_MBC 0x0003 /* mic boost */ | ||
| 1655 | #define AC97_AD1986_MBC_20 0x0000 /* +20dB */ | ||
| 1656 | #define AC97_AD1986_MBC_10 0x0001 /* +10dB */ | ||
| 1657 | #define AC97_AD1986_MBC_30 0x0002 /* +30dB */ | ||
| 1658 | #define AC97_AD1986_LISEL0 0x0004 /* LINE_IN select bit 0 */ | ||
| 1659 | #define AC97_AD1986_LISEL1 0x0008 /* LINE_IN select bit 1 */ | ||
| 1660 | #define AC97_AD1986_LISEL_MASK (AC97_AD1986_LISEL1 | AC97_AD1986_LISEL0) | ||
| 1661 | #define AC97_AD1986_LISEL_LI 0x0000 /* LINE_IN pins as LINE_IN source */ | ||
| 1662 | #define AC97_AD1986_LISEL_SURR 0x0004 /* SURROUND pins as LINE_IN source */ | ||
| 1663 | #define AC97_AD1986_LISEL_MIC 0x0008 /* MIC_1/2 pins as LINE_IN source */ | ||
| 1664 | #define AC97_AD1986_SRU 0x0010 /* sample rate unlock */ | ||
| 1665 | #define AC97_AD1986_SOSEL 0x0020 /* SURROUND_OUT amplifiers input sel */ | ||
| 1666 | #define AC97_AD1986_2MIC 0x0040 /* 2-channel mic select */ | ||
| 1667 | #define AC97_AD1986_SPRD 0x0080 /* SPREAD enable */ | ||
| 1668 | #define AC97_AD1986_DMIX0 0x0100 /* downmix mode: */ | ||
| 1669 | /* 0 = 6-to-4, 1 = 6-to-2 downmix */ | ||
| 1670 | #define AC97_AD1986_DMIX1 0x0200 /* downmix mode: 1 = enabled */ | ||
| 1671 | #define AC97_AD1986_CLDIS 0x0800 /* center/lfe disable */ | ||
| 1672 | #define AC97_AD1986_SODIS 0x1000 /* SURROUND_OUT disable */ | ||
| 1673 | #define AC97_AD1986_MSPLT 0x2000 /* mute split (read only 1) */ | ||
| 1674 | #define AC97_AD1986_AC97NC 0x4000 /* AC97 no compatible mode (r/o 1) */ | ||
| 1675 | #define AC97_AD1986_DACZ 0x8000 /* DAC zero-fill mode */ | ||
| 1676 | |||
| 1677 | /* MISC 2 bits (AD1986 register 0x70) */ | ||
| 1678 | #define AC97_AD_MISC2 0x70 /* Misc Control Bits 2 (AD1986) */ | ||
| 1679 | |||
| 1680 | #define AC97_AD1986_CVREF0 0x0004 /* C/LFE VREF_OUT 2.25V */ | ||
| 1681 | #define AC97_AD1986_CVREF1 0x0008 /* C/LFE VREF_OUT 0V */ | ||
| 1682 | #define AC97_AD1986_CVREF2 0x0010 /* C/LFE VREF_OUT 3.7V */ | ||
| 1683 | #define AC97_AD1986_CVREF_MASK \ | ||
| 1684 | (AC97_AD1986_CVREF2 | AC97_AD1986_CVREF1 | AC97_AD1986_CVREF0) | ||
| 1685 | #define AC97_AD1986_JSMAP 0x0020 /* Jack Sense Mapping 1 = alternate */ | ||
| 1686 | #define AC97_AD1986_MMDIS 0x0080 /* Mono Mute Disable */ | ||
| 1687 | #define AC97_AD1986_MVREF0 0x0400 /* MIC VREF_OUT 2.25V */ | ||
| 1688 | #define AC97_AD1986_MVREF1 0x0800 /* MIC VREF_OUT 0V */ | ||
| 1689 | #define AC97_AD1986_MVREF2 0x1000 /* MIC VREF_OUT 3.7V */ | ||
| 1690 | #define AC97_AD1986_MVREF_MASK \ | ||
| 1691 | (AC97_AD1986_MVREF2 | AC97_AD1986_MVREF1 | AC97_AD1986_MVREF0) | ||
| 1692 | |||
| 1693 | /* MISC 3 bits (AD1986 register 0x7a) */ | ||
| 1694 | #define AC97_AD_MISC3 0x7a /* Misc Control Bits 3 (AD1986) */ | ||
| 1695 | |||
| 1696 | #define AC97_AD1986_MMIX 0x0004 /* Mic Mix, left/right */ | ||
| 1697 | #define AC97_AD1986_GPO 0x0008 /* General Purpose Out */ | ||
| 1698 | #define AC97_AD1986_LOHPEN 0x0010 /* LINE_OUT headphone drive */ | ||
| 1699 | #define AC97_AD1986_LVREF0 0x0100 /* LINE_OUT VREF_OUT 2.25V */ | ||
| 1700 | #define AC97_AD1986_LVREF1 0x0200 /* LINE_OUT VREF_OUT 0V */ | ||
| 1701 | #define AC97_AD1986_LVREF2 0x0400 /* LINE_OUT VREF_OUT 3.7V */ | ||
| 1702 | #define AC97_AD1986_LVREF_MASK \ | ||
| 1703 | (AC97_AD1986_LVREF2 | AC97_AD1986_LVREF1 | AC97_AD1986_LVREF0) | ||
| 1704 | #define AC97_AD1986_JSINVA 0x0800 /* Jack Sense Invert SENSE_A */ | ||
| 1705 | #define AC97_AD1986_LOSEL 0x1000 /* LINE_OUT amplifiers input select */ | ||
| 1706 | #define AC97_AD1986_HPSEL0 0x2000 /* Headphone amplifiers */ | ||
| 1707 | /* input select Surround DACs */ | ||
| 1708 | #define AC97_AD1986_HPSEL1 0x4000 /* Headphone amplifiers input */ | ||
| 1709 | /* select C/LFE DACs */ | ||
| 1710 | #define AC97_AD1986_JSINVB 0x8000 /* Jack Sense Invert SENSE_B */ | ||
| 1711 | |||
| 1712 | /* Serial Config bits (AD1986 register 0x74) (incomplete) */ | ||
| 1713 | #define AC97_AD1986_OMS0 0x0100 /* Optional Mic Selector bit 0 */ | ||
| 1714 | #define AC97_AD1986_OMS1 0x0200 /* Optional Mic Selector bit 1 */ | ||
| 1715 | #define AC97_AD1986_OMS2 0x0400 /* Optional Mic Selector bit 2 */ | ||
| 1716 | #define AC97_AD1986_OMS_MASK \ | ||
| 1717 | (AC97_AD1986_OMS2 | AC97_AD1986_OMS1 | AC97_AD1986_OMS0) | ||
| 1718 | #define AC97_AD1986_OMS_M 0x0000 /* MIC_1/2 pins are MIC sources */ | ||
| 1719 | #define AC97_AD1986_OMS_L 0x0100 /* LINE_IN pins are MIC sources */ | ||
| 1720 | #define AC97_AD1986_OMS_C 0x0200 /* Center/LFE pins are MCI sources */ | ||
| 1721 | #define AC97_AD1986_OMS_MC 0x0400 /* Mix of MIC and C/LFE pins */ | ||
| 1722 | /* are MIC sources */ | ||
| 1723 | #define AC97_AD1986_OMS_ML 0x0500 /* MIX of MIC and LINE_IN pins */ | ||
| 1724 | /* are MIC sources */ | ||
| 1725 | #define AC97_AD1986_OMS_LC 0x0600 /* MIX of LINE_IN and C/LFE pins */ | ||
| 1726 | /* are MIC sources */ | ||
| 1727 | #define AC97_AD1986_OMS_MLC 0x0700 /* MIX of MIC, LINE_IN, C/LFE pins */ | ||
| 1728 | /* are MIC sources */ | ||
| 1729 | |||
| 1653 | 1730 | ||
| 1654 | static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1731 | static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
| 1655 | { | 1732 | { |
| @@ -2105,6 +2182,294 @@ int patch_ad1985(struct snd_ac97 * ac97) | |||
| 2105 | return 0; | 2182 | return 0; |
| 2106 | } | 2183 | } |
| 2107 | 2184 | ||
| 2185 | static int snd_ac97_ad1986_bool_info(struct snd_kcontrol *kcontrol, | ||
| 2186 | struct snd_ctl_elem_info *uinfo) | ||
| 2187 | { | ||
| 2188 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
| 2189 | uinfo->count = 1; | ||
| 2190 | uinfo->value.integer.min = 0; | ||
| 2191 | uinfo->value.integer.max = 1; | ||
| 2192 | return 0; | ||
| 2193 | } | ||
| 2194 | |||
| 2195 | static int snd_ac97_ad1986_lososel_get(struct snd_kcontrol *kcontrol, | ||
| 2196 | struct snd_ctl_elem_value *ucontrol) | ||
| 2197 | { | ||
| 2198 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | ||
| 2199 | unsigned short val; | ||
| 2200 | |||
| 2201 | val = ac97->regs[AC97_AD_MISC3]; | ||
| 2202 | ucontrol->value.integer.value[0] = (val & AC97_AD1986_LOSEL) != 0; | ||
| 2203 | return 0; | ||
| 2204 | } | ||
| 2205 | |||
| 2206 | static int snd_ac97_ad1986_lososel_put(struct snd_kcontrol *kcontrol, | ||
| 2207 | struct snd_ctl_elem_value *ucontrol) | ||
| 2208 | { | ||
| 2209 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | ||
| 2210 | int ret0; | ||
| 2211 | int ret1; | ||
| 2212 | int sprd = (ac97->regs[AC97_AD_MISC] & AC97_AD1986_SPRD) != 0; | ||
| 2213 | |||
| 2214 | ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC3, AC97_AD1986_LOSEL, | ||
| 2215 | ucontrol->value.integer.value[0] != 0 | ||
| 2216 | ? AC97_AD1986_LOSEL : 0); | ||
| 2217 | if (ret0 < 0) | ||
| 2218 | return ret0; | ||
| 2219 | |||
| 2220 | /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */ | ||
| 2221 | ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL, | ||
| 2222 | (ucontrol->value.integer.value[0] != 0 | ||
| 2223 | || sprd) | ||
| 2224 | ? AC97_AD1986_SOSEL : 0); | ||
| 2225 | if (ret1 < 0) | ||
| 2226 | return ret1; | ||
| 2227 | |||
| 2228 | return (ret0 > 0 || ret1 > 0) ? 1 : 0; | ||
| 2229 | } | ||
| 2230 | |||
| 2231 | static int snd_ac97_ad1986_spread_get(struct snd_kcontrol *kcontrol, | ||
| 2232 | struct snd_ctl_elem_value *ucontrol) | ||
| 2233 | { | ||
| 2234 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | ||
| 2235 | unsigned short val; | ||
| 2236 | |||
| 2237 | val = ac97->regs[AC97_AD_MISC]; | ||
| 2238 | ucontrol->value.integer.value[0] = (val & AC97_AD1986_SPRD) != 0; | ||
| 2239 | return 0; | ||
| 2240 | } | ||
| 2241 | |||
| 2242 | static int snd_ac97_ad1986_spread_put(struct snd_kcontrol *kcontrol, | ||
| 2243 | struct snd_ctl_elem_value *ucontrol) | ||
| 2244 | { | ||
| 2245 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | ||
| 2246 | int ret0; | ||
| 2247 | int ret1; | ||
| 2248 | int sprd = (ac97->regs[AC97_AD_MISC3] & AC97_AD1986_LOSEL) != 0; | ||
| 2249 | |||
| 2250 | ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SPRD, | ||
| 2251 | ucontrol->value.integer.value[0] != 0 | ||
| 2252 | ? AC97_AD1986_SPRD : 0); | ||
| 2253 | if (ret0 < 0) | ||
| 2254 | return ret0; | ||
| 2255 | |||
| 2256 | /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */ | ||
| 2257 | ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL, | ||
| 2258 | (ucontrol->value.integer.value[0] != 0 | ||
| 2259 | || sprd) | ||
| 2260 | ? AC97_AD1986_SOSEL : 0); | ||
| 2261 | if (ret1 < 0) | ||
| 2262 | return ret1; | ||
| 2263 | |||
| 2264 | return (ret0 > 0 || ret1 > 0) ? 1 : 0; | ||
| 2265 | } | ||
| 2266 | |||
| 2267 | static int snd_ac97_ad1986_miclisel_get(struct snd_kcontrol *kcontrol, | ||
| 2268 | struct snd_ctl_elem_value *ucontrol) | ||
| 2269 | { | ||
| 2270 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | ||
| 2271 | |||
| 2272 | ucontrol->value.integer.value[0] = ac97->spec.ad18xx.swap_mic_linein; | ||
| 2273 | return 0; | ||
| 2274 | } | ||
| 2275 | |||
| 2276 | static int snd_ac97_ad1986_miclisel_put(struct snd_kcontrol *kcontrol, | ||
| 2277 | struct snd_ctl_elem_value *ucontrol) | ||
| 2278 | { | ||
| 2279 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | ||
| 2280 | unsigned char swap = ucontrol->value.integer.value[0] != 0; | ||
| 2281 | |||
| 2282 | if (swap != ac97->spec.ad18xx.swap_mic_linein) { | ||
| 2283 | ac97->spec.ad18xx.swap_mic_linein = swap; | ||
| 2284 | if (ac97->build_ops->update_jacks) | ||
| 2285 | ac97->build_ops->update_jacks(ac97); | ||
| 2286 | return 1; | ||
| 2287 | } | ||
| 2288 | return 0; | ||
| 2289 | } | ||
| 2290 | |||
| 2291 | static int snd_ac97_ad1986_vrefout_get(struct snd_kcontrol *kcontrol, | ||
| 2292 | struct snd_ctl_elem_value *ucontrol) | ||
| 2293 | { | ||
| 2294 | /* Use MIC_1/2 V_REFOUT as the "get" value */ | ||
| 2295 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | ||
| 2296 | unsigned short val; | ||
| 2297 | unsigned short reg = ac97->regs[AC97_AD_MISC2]; | ||
| 2298 | if ((reg & AC97_AD1986_MVREF0) != 0) | ||
| 2299 | val = 2; | ||
| 2300 | else if ((reg & AC97_AD1986_MVREF1) != 0) | ||
| 2301 | val = 3; | ||
| 2302 | else if ((reg & AC97_AD1986_MVREF2) != 0) | ||
| 2303 | val = 1; | ||
| 2304 | else | ||
| 2305 | val = 0; | ||
| 2306 | ucontrol->value.enumerated.item[0] = val; | ||
| 2307 | return 0; | ||
| 2308 | } | ||
| 2309 | |||
| 2310 | static int snd_ac97_ad1986_vrefout_put(struct snd_kcontrol *kcontrol, | ||
| 2311 | struct snd_ctl_elem_value *ucontrol) | ||
| 2312 | { | ||
| 2313 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | ||
| 2314 | unsigned short cval; | ||
| 2315 | unsigned short lval; | ||
| 2316 | unsigned short mval; | ||
| 2317 | int cret; | ||
| 2318 | int lret; | ||
| 2319 | int mret; | ||
| 2320 | |||
| 2321 | switch (ucontrol->value.enumerated.item[0]) | ||
| 2322 | { | ||
| 2323 | case 0: /* High-Z */ | ||
| 2324 | cval = 0; | ||
| 2325 | lval = 0; | ||
| 2326 | mval = 0; | ||
| 2327 | break; | ||
| 2328 | case 1: /* 3.7 V */ | ||
| 2329 | cval = AC97_AD1986_CVREF2; | ||
| 2330 | lval = AC97_AD1986_LVREF2; | ||
| 2331 | mval = AC97_AD1986_MVREF2; | ||
| 2332 | break; | ||
| 2333 | case 2: /* 2.25 V */ | ||
| 2334 | cval = AC97_AD1986_CVREF0; | ||
| 2335 | lval = AC97_AD1986_LVREF0; | ||
| 2336 | mval = AC97_AD1986_MVREF0; | ||
| 2337 | break; | ||
| 2338 | case 3: /* 0 V */ | ||
| 2339 | cval = AC97_AD1986_CVREF1; | ||
| 2340 | lval = AC97_AD1986_LVREF1; | ||
| 2341 | mval = AC97_AD1986_MVREF1; | ||
| 2342 | break; | ||
| 2343 | default: | ||
| 2344 | return -EINVAL; | ||
| 2345 | } | ||
| 2346 | |||
| 2347 | cret = snd_ac97_update_bits(ac97, AC97_AD_MISC2, | ||
| 2348 | AC97_AD1986_CVREF_MASK, cval); | ||
| 2349 | if (cret < 0) | ||
| 2350 | return cret; | ||
| 2351 | lret = snd_ac97_update_bits(ac97, AC97_AD_MISC3, | ||
| 2352 | AC97_AD1986_LVREF_MASK, lval); | ||
| 2353 | if (lret < 0) | ||
| 2354 | return lret; | ||
| 2355 | mret = snd_ac97_update_bits(ac97, AC97_AD_MISC2, | ||
| 2356 | AC97_AD1986_MVREF_MASK, mval); | ||
| 2357 | if (mret < 0) | ||
| 2358 | return mret; | ||
| 2359 | |||
| 2360 | return (cret > 0 || lret > 0 || mret > 0) ? 1 : 0; | ||
| 2361 | } | ||
| 2362 | |||
| 2363 | static const struct snd_kcontrol_new snd_ac97_ad1986_controls[] = { | ||
| 2364 | AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0), | ||
| 2365 | { | ||
| 2366 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 2367 | .name = "Exchange Front/Surround", | ||
| 2368 | .info = snd_ac97_ad1986_bool_info, | ||
| 2369 | .get = snd_ac97_ad1986_lososel_get, | ||
| 2370 | .put = snd_ac97_ad1986_lososel_put | ||
| 2371 | }, | ||
| 2372 | { | ||
| 2373 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 2374 | .name = "Exchange Mic/Line In", | ||
| 2375 | .info = snd_ac97_ad1986_bool_info, | ||
| 2376 | .get = snd_ac97_ad1986_miclisel_get, | ||
| 2377 | .put = snd_ac97_ad1986_miclisel_put | ||
| 2378 | }, | ||
| 2379 | { | ||
| 2380 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 2381 | .name = "Spread Front to Surround and Center/LFE", | ||
| 2382 | .info = snd_ac97_ad1986_bool_info, | ||
| 2383 | .get = snd_ac97_ad1986_spread_get, | ||
| 2384 | .put = snd_ac97_ad1986_spread_put | ||
| 2385 | }, | ||
| 2386 | { | ||
| 2387 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 2388 | .name = "Downmix", | ||
| 2389 | .info = snd_ac97_ad1888_downmix_info, | ||
| 2390 | .get = snd_ac97_ad1888_downmix_get, | ||
| 2391 | .put = snd_ac97_ad1888_downmix_put | ||
| 2392 | }, | ||
| 2393 | { | ||
| 2394 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 2395 | .name = "V_REFOUT", | ||
| 2396 | .info = snd_ac97_ad1985_vrefout_info, | ||
| 2397 | .get = snd_ac97_ad1986_vrefout_get, | ||
| 2398 | .put = snd_ac97_ad1986_vrefout_put | ||
| 2399 | }, | ||
| 2400 | AC97_SURROUND_JACK_MODE_CTL, | ||
| 2401 | AC97_CHANNEL_MODE_CTL, | ||
| 2402 | |||
| 2403 | AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0), | ||
| 2404 | AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0) | ||
| 2405 | }; | ||
| 2406 | |||
| 2407 | static void ad1986_update_jacks(struct snd_ac97 *ac97) | ||
| 2408 | { | ||
| 2409 | unsigned short misc_val = 0; | ||
| 2410 | unsigned short ser_val; | ||
| 2411 | |||
| 2412 | /* disable SURROUND and CENTER/LFE if not surround mode */ | ||
| 2413 | if (! is_surround_on(ac97)) | ||
| 2414 | misc_val |= AC97_AD1986_SODIS; | ||
| 2415 | if (! is_clfe_on(ac97)) | ||
| 2416 | misc_val |= AC97_AD1986_CLDIS; | ||
| 2417 | |||
| 2418 | /* select line input (default=LINE_IN, SURROUND or MIC_1/2) */ | ||
| 2419 | if (is_shared_linein(ac97)) | ||
| 2420 | misc_val |= AC97_AD1986_LISEL_SURR; | ||
| 2421 | else if (ac97->spec.ad18xx.swap_mic_linein != 0) | ||
| 2422 | misc_val |= AC97_AD1986_LISEL_MIC; | ||
| 2423 | snd_ac97_update_bits(ac97, AC97_AD_MISC, | ||
| 2424 | AC97_AD1986_SODIS | AC97_AD1986_CLDIS | | ||
| 2425 | AC97_AD1986_LISEL_MASK, | ||
| 2426 | misc_val); | ||
| 2427 | |||
| 2428 | /* select microphone input (MIC_1/2, Center/LFE or LINE_IN) */ | ||
| 2429 | if (is_shared_micin(ac97)) | ||
| 2430 | ser_val = AC97_AD1986_OMS_C; | ||
| 2431 | else if (ac97->spec.ad18xx.swap_mic_linein != 0) | ||
| 2432 | ser_val = AC97_AD1986_OMS_L; | ||
| 2433 | else | ||
| 2434 | ser_val = AC97_AD1986_OMS_M; | ||
| 2435 | snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, | ||
| 2436 | AC97_AD1986_OMS_MASK, | ||
| 2437 | ser_val); | ||
| 2438 | } | ||
| 2439 | |||
| 2440 | static int patch_ad1986_specific(struct snd_ac97 *ac97) | ||
| 2441 | { | ||
| 2442 | int err; | ||
| 2443 | |||
| 2444 | if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0) | ||
| 2445 | return err; | ||
| 2446 | |||
| 2447 | return patch_build_controls(ac97, snd_ac97_ad1986_controls, | ||
| 2448 | ARRAY_SIZE(snd_ac97_ad1985_controls)); | ||
| 2449 | } | ||
| 2450 | |||
| 2451 | static struct snd_ac97_build_ops patch_ad1986_build_ops = { | ||
| 2452 | .build_post_spdif = patch_ad198x_post_spdif, | ||
| 2453 | .build_specific = patch_ad1986_specific, | ||
| 2454 | #ifdef CONFIG_PM | ||
| 2455 | .resume = ad18xx_resume, | ||
| 2456 | #endif | ||
| 2457 | .update_jacks = ad1986_update_jacks, | ||
| 2458 | }; | ||
| 2459 | |||
| 2460 | int patch_ad1986(struct snd_ac97 * ac97) | ||
| 2461 | { | ||
| 2462 | patch_ad1881(ac97); | ||
| 2463 | ac97->build_ops = &patch_ad1986_build_ops; | ||
| 2464 | ac97->flags |= AC97_STEREO_MUTES; | ||
| 2465 | |||
| 2466 | /* update current jack configuration */ | ||
| 2467 | ad1986_update_jacks(ac97); | ||
| 2468 | |||
| 2469 | return 0; | ||
| 2470 | } | ||
| 2471 | |||
| 2472 | |||
| 2108 | /* | 2473 | /* |
| 2109 | * realtek ALC65x/850 codecs | 2474 | * realtek ALC65x/850 codecs |
| 2110 | */ | 2475 | */ |
diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h index 7419792172..94340daaaf 100644 --- a/sound/pci/ac97/ac97_patch.h +++ b/sound/pci/ac97/ac97_patch.h | |||
| @@ -48,6 +48,7 @@ int patch_ad1980(struct snd_ac97 * ac97); | |||
| 48 | int patch_ad1981a(struct snd_ac97 * ac97); | 48 | int patch_ad1981a(struct snd_ac97 * ac97); |
| 49 | int patch_ad1981b(struct snd_ac97 * ac97); | 49 | int patch_ad1981b(struct snd_ac97 * ac97); |
| 50 | int patch_ad1985(struct snd_ac97 * ac97); | 50 | int patch_ad1985(struct snd_ac97 * ac97); |
| 51 | int patch_ad1986(struct snd_ac97 * ac97); | ||
| 51 | int patch_alc650(struct snd_ac97 * ac97); | 52 | int patch_alc650(struct snd_ac97 * ac97); |
| 52 | int patch_alc655(struct snd_ac97 * ac97); | 53 | int patch_alc655(struct snd_ac97 * ac97); |
| 53 | int patch_alc850(struct snd_ac97 * ac97); | 54 | int patch_alc850(struct snd_ac97 * ac97); |
