Repository navigation
Conversation
…leep Since the speaker volumes are locked from suspend-prepare, the speakers stay silent after the first system sleep. Locking clips every speaker volume to the lock's ceiling (1, -100 dB on the SN012776), and unlocking only lifts the ceiling again. After a lost lease that is fine: speakersafetyd gets -ETIMEDOUT, restarts and sets the volumes itself. The system-sleep lock is deliberately not reported as a lost lease, so the daemon keeps its state and never writes the volumes again. They stay at -100 dB until the daemon restarts. alsactl then stores them that way at shutdown, and restores them on the next boot. Keep the speaker volumes at suspend-prepare, before the lock clips them, and set them again at the first unlock after it. That is the daemon's first ping after the resume, which in practice comes when playback next starts. These are the values the daemon set and still assumes. The daemon may not ping between two sleeps. A suspend-prepare that finds the volumes locked already keeps what an earlier one saved, so a second sleep before any playback doesn't lose them. Hold the card's controls for reading from keeping the volumes until they are clipped, so a volume the daemon writes meanwhile can't be overwritten by an older, higher one at the unlock. Hold them as well in the work that can unlock after a back-end starts or stops, so setting the volumes again there doesn't race a volume write either. Control writes hold them for writing and take volume_lock_mutex inside, in the same order. A new owner of the lock, such as a restarted daemon, sets the volumes itself: drop what was kept then, and when the card is removed. Nothing is kept for a card that is shutting down. Tested on a J713: after a suspend-to-idle the four speaker volumes are back at 0 dB and the speakers play, without restarting speakersafetyd. The KUnit cases go through the lock control and the PM notifier: one sleep, two sleeps before the daemon pings, and a new owner after a sleep. Fixes: 1cbce20 ("ASoC: apple: macaudio: lock the speaker volumes before userspace freezes") Signed-off-by: Erik Bourget <erik@ebourget.net>
|
Confirmed on a J616s (MacBook Pro 16" M4 Pro, T6040), and agreed on the cause. 1cbce20 is my commit; thanks for catching this. Reproduced on 7.3.0-m4.75, which carries 1cbce20 (no fix):
Why the daemon never writes them back: speakersafetyd writes a volume only when its computed gain changes ( On "also across reboots": here a reboot clears it. speakersafetyd's warm-boot flag is under On the fix (read only, not built or run here):
Analysis done with Claude (Anthropic). |
|
Superseded by #820 (commit 17). Two changes:
|
Problem
Since 1cbce20 ("ASoC: apple: macaudio: lock the speaker volumes before userspace freezes"), the speakers are silent after the first system sleep. They stay silent until speakersafetyd is restarted, and also across reboots: alsactl stores the muted volumes at shutdown and restores them at the next boot.
Cause
Locking the speaker volumes clips every speaker volume control to the lock's ceiling. On the SN012776 that is 1, or -100 dB. Unlocking only lifts the ceiling again; it doesn't set the volumes back.
After a lease the daemon lost, that is fine: speakersafetyd gets -ETIMEDOUT on its next ping, restarts and sets the volumes itself. The system-sleep lock is deliberately not reported as a lost lease, so that the daemon keeps its speaker temperatures. As a result, nothing ever sets the volumes again: the daemon still assumes the values it wrote before the sleep.
Fix
At suspend-prepare, before the lock clips them, keep the speaker volumes. At the first unlock after that, set them again. That unlock is the daemon's first ping after the resume, which can come only when playback next starts. These are the values the daemon set and still assumes, so its state and the hardware agree again.
volume_lock_mutexinside, in the same order.The lock itself is unchanged: the volumes are still clipped from suspend-prepare until the daemon's first ping after the resume.
Testing
On a J713 (MacBook Air 13" M4), with this fix applied to our J713 tree (which has the J713 speaker support):
KUnit: a new
apple-speaker-pm-volumessuite drives the real lock control callbacks (slk_lock,slk_put) and the PM notifier, with volume controls backed bysoc_mixer_control, so the actual clip runs. It covers one sleep, two sleeps before the daemon pings, and a new owner after a sleep. The two-sleep case fails without the keep-while-locked change. It runs with the existing admission suite under arm64 QEMU with KASAN and lockdep: 4/4 pass, no reports.checkpatch
--strict: no errors. Two notes remain: the MAINTAINERS warning is covered by the existingsound/soc/apple/*entry, and the blank-line check beforekunit_test_suite()follows the existing admission test header. W=1 builds ofmacaudio.oare clean, built in and as a module.This fix was developed and tested by Claude (Anthropic), working with me on the J713.