Slackware Linux, but custom-configured kernel from kernel.org
IBM ThinkPad X22
Intel Corporation 82801CA/CAM AC'97 Audio Controller
When resuming from disk, the AC97 registers are not restored.
alsamixer shows me correct values - the settings from before
the suspension - but they are not in sync with the hardware.
When I change (mute/unmute or increase/decrease) the volume,
the settings for the specific channel are getting back in sync.
So after suspend-resume, I modify Master and PCM and sound is
Steps to reproduce:
0. Have an intel8x0 ICH3 soundcard using the Cirrus Logic CS4299 rev 6 AC-97 codec.
1. Do some mixer settings with alsamixer.
2. Suspend the box.
3. Resume the box.
4. Have no sound until you change settings for the channels you have to use (Master and PCM in my case).
What I found out myself:
I debugged the snd_ac97_write()'s in snd_ac97_restore_status() by printing what the cache register contains before it is written to the hardware register and then printing the return value of snd_ac97_read(). This was in my dmesg after a suspend/resume cycle:
snd_ac97_restore_status(): restoring register 0x2 to value 0x0
snd_ac97_restore_status(): register 0x2 now contains 0x8000
snd_ac97_restore_status(): restoring register 0x4 to value 0x91f
snd_ac97_restore_status(): register 0x4 now contains 0x8000
The values that should be written out reflect the true settings that were valid before the suspension. But they seem not to be written out to the regs.
$ cat /proc/asound/card0/codec97#0/codec97#0-0+regs > before
$ cat /proc/asound/card0/codec97#0/codec97#0-0+regs > after
$ diff -Naur before after
-0:02 = 0000
-0:04 = 91f1
+0:02 = 8000
+0:04 = 8000
Hope this helps,
I have found a fix for it, patch attached.
This also works for the laptop of my girlfriend that (who?) had the same problem as described.
Distro: Gentoo Linux, custom-configured kernel from kernel.org version 126.96.36.199
Hardware: HP Compaq nx6125 with atiixp sb400, ac97 codec: Conexant id 30
Created attachment 11744 [details]
[PATCH] AC97: Restore codec registers more assertive on resume
Patched against current snapshot of linux-2.6.git. Tested successfully on two boxes using AC97 codec with different hardware.
Crap, my girlfriend noticed that the sound randomly stays muted. I'll investigate on it.
Further experiments showed up, that either the waiting times in ac97_codec.c should be increased or that the driver-specific _codec_read/_codec_write functions should be more caring that it happens what they are up to.
I found out that it is important before writing the device, there should be a wait-loop for the AC97_POWERDOWN register to become !0.
Increasing the timeouts in the loops 'fixes' the problem in the sense that the registers are restored properly, but I don't think that it is the right place for fixing. The codec should not take up to 2 seconds to get ready.
Can you check if this problem is also present in the 2.6.23-rc2 kernel?
I tried it with 2.6.23-rc4, the registers still don't get restored.
I catted /proc/asound/card0/codec97#0/ac97#0-0+regs before and after the resume, without doing anything in between.
Here is the diff:
symbol [~] :) diff -Naur asound-regs-before asound-regs-after
--- asound-regs-before 2007-08-30 17:21:13.000000000 +0200
+++ asound-regs-after 2007-08-30 17:22:05.000000000 +0200
@@ -1,5 +1,5 @@
0:00 = 1990
-0:02 = 0000
+0:02 = 8000
0:04 = 8000
0:06 = 8000
0:08 = 0000
@@ -10,7 +10,7 @@
0:12 = 8808
0:14 = 8808
0:16 = 8808
-0:18 = 0c0c
+0:18 = 8808
0:1a = 0000
0:1c = 8000
0:1e = 0000
I can try with 2.6.23-rc2 if that is important.
Closing out old stale bugs