kern/140591: [PATCH][sound] No sound output on lineout/headphone jacks using AD1980 AC'97 codec chip (Fujitsu C610)

kabe at sra-tohoku.co.jp kabe at sra-tohoku.co.jp
Mon Nov 16 02:30:02 UTC 2009


>Number:         140591
>Category:       kern
>Synopsis:       [PATCH][sound] No sound output on lineout/headphone jacks using AD1980 AC'97 codec chip (Fujitsu C610)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Nov 16 02:30:01 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator:     kabe at sra-tohoku.co.jp
>Release:        FreeBSD 7.2-RELEASE i386
>Organization:
-
>Environment:
System: FreeBSD capricorn.five.ten 7.2-RELEASE FreeBSD 7.2-RELEASE #0: Fri Nov 13 02:26:07 JST 2009 kabe at capricorn.five.ten:/usr/obj/usr/src/sys/GENERIC i386
	Fujitsu (Fujitsu-Siemens) C610
	Intel ICH5 + AD1980 AC'97 codec
>Description:
	Internal speaker perfectly works, but
	headphone or lineout jacks have no audio output.
>How-To-Repeat:
	With motherboards with AD1980 codec, and monitoring its LINE_OUT pins,
	play some audio. No audio output.
	SURR_OUT/HP_OUT pins will have output.
	These AD1980 pins may be wired in various ways to lineout/headphone/internal
	speakers, and some configuration (particulary laptops) may not have
	one of the output wired.
>Fix:
	The patch below will only fix Fujitsu C610,
	but just collapsing into 

void ad198x_patch(struct ac97_info* codec)
{
	ac97_wrcd(codec, 0x76, ac97_rdcd(codec, 0x76) | 0x0400);
}

	seems to be the better solution. Also backportable to older FreeBSD.

(cd /usr/src; env TZ=GMT diff -u sys/dev/sound/pcm/ac97_patch.c{.dist,})
--- sys/dev/sound/pcm/ac97_patch.c.dist	2009-04-15 03:14:26.000000000 +0000
+++ sys/dev/sound/pcm/ac97_patch.c	2009-11-15 16:10:10.000000000 +0000
@@ -44,9 +44,46 @@
 
 void ad198x_patch(struct ac97_info* codec)
 {
+	/*
+	 * AD198x series have 2 pairs of analog output: 
+	 * SURR_OUT/HP_OUT(surround or headphone) and LINE_OUT.
+	 *
+	 * Since SURR_OUT/HP_OUT output pins are equipped with power amps, 
+	 * retail machines often wire these to headphones jacks and/or 
+	 * internal speakers.
+	 * This also means "mixer phout" will adjust speaker volume 
+	 * and "mixer vol" adjust lineout level, _independently_.
+	 *
+	 * (Linux has flags to swap vol/phout, and FreeBSD can do similar 
+	 *  by mix_setrealdev() and gang them with mix_setparentchild())
+	 *
+	 * AD198x register 0x76
+	 * 0x0400: select mixer for SURR_OUT/HP_OUT output pins (default surround DAC)
+	 * 0x0020: select surround DAC for LINE_OUT output pins (default mixer)
+	 *
+	 * Selecting surround DAC for any output will yield "no sound", 
+	 * until FreeBSD supports surround DAC handling.
+	 *
+	 * Previous ad198x_patch() had set 0x0420, but 0x0400 seems to be 
+	 * better for all instances. At least you have mixer output 
+	 * for all output pins.
+	 * The value is valid for all AD1888, AD1980, AD1985 and AD1986.
+	 * (AD1986, having independent SURR_OUT and HP_OUT, will select
+	 * mixer output for SURR_OUT by setting 0x0400 bit.)
+	 *
+	 * Fujitsu C610 seems to wire SURR_OUT/HP_OUT for 
+	 * internal speaker, and LINE_OUT for lineout AND headphone jacks; 
+	 * by setting previous 0x0420, internal speaker works but 
+	 * no output for either jacks.
+	 * ASUS A9T may had been working by not setting the register because 
+	 * it only wired LINE_OUT.
+	 */
 	switch (ac97_getsubvendor(codec)) {
 	case 0x11931043:	/* Not for ASUS A9T (probably else too). */
 		break;
+	case 0x122f10cf:	/* Fujitsu C610 (perhaps for others) */
+		ac97_wrcd(codec, 0x76, ac97_rdcd(codec, 0x76) | 0x0400);
+		break;
 	default:
 		ac97_wrcd(codec, 0x76, ac97_rdcd(codec, 0x76) | 0x0420);
 		break;
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list