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 9da4977c0a0c..bd8cfdcfbdf1 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 bd27531a0f0e..f5b4b44bbdab 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 741979217207..94340daaaf1f 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); |