The Speakers Were Fine. The Amplifier Was Asleep.
My laptop's internal speakers were silent on Linux but worked on Windows. Every software layer said audio was playing — I even recorded an 80%-amplitude signal off the sink. The speakers weren't broken: the Cirrus Logic CS35L41 smart amplifiers never engaged, and the kernel 6.8 driver couldn't wake them on an HP Envy x360. Here's the full diagnostic path and the one-line fix.
My laptop had no sound. Internal speakers, dead silent — but the same machine had working audio in Windows. The obvious guesses were a muted channel, a missing driver, or, worst case, blown speakers. None of those was it. The speakers were perfectly healthy the entire time. The chip that’s supposed to drive them was asleep, and every diagnostic tool I reached for happily reported success at a layer above the one that was actually broken.
This is the same trap as a green test suite running on the wrong database: the instrument measures the thing it can reach, declares victory, and says nothing about the thing that’s failing one layer down.
Just want the fix? Start here
If you found this because your laptop speakers went silent on Linux and you don’t care about the why, here’s the whole fix in order. Stop as soon as sound comes back. You’ll be asked for your password along the way — that’s normal.
-
Check the basics first. Open your sound settings and make sure the output isn’t muted, the volume is up, and the correct device is selected — your speakers, not HDMI or headphones. Surprisingly often, that’s the whole problem.
-
Turn off Auto-Mute. On many HP laptops the speakers get muted by a setting that thinks headphones are plugged in when they aren’t. Open a terminal and run:
amixer -c1 sset 'Auto-Mute Mode' DisabledThen test sound. (If you get a “control not found” error, your sound card is a different number — try
-c0instead of-c1.) If sound comes back, make it permanent withsudo alsactl storeand you’re done. -
Update to a newer kernel. Still silent? Your kernel is likely too old to wake the speaker amplifier chip. On Ubuntu or Linux Mint:
sudo apt install --install-recommends linux-generic-hwe-24.04 sudo rebootOn a rolling distro like Arch or Fedora, just update to the latest kernel and reboot.
-
Test again. Play any audio. For most people on a recent HP Envy or Pavilion, step 2 or step 3 is the fix — and your speakers were never the problem.
Prefer one command? I wrote a small script that does exactly the safe steps above — it detects your hardware, applies only the reversible fixes, re-tests while watching the amplifier wake up, and (deliberately) just prints the kernel-upgrade command instead of running it. It never installs a kernel, never reboots you, and supports --dry-run to diagnose without changing anything:
curl -fsSL https://www.kennethlacroix.me/scripts/fix-linux-speakers.sh -o fix-linux-speakers.sh
less fix-linux-speakers.sh # read it first — never pipe a stranger's script straight to a shell
bash fix-linux-speakers.sh --dry-run # diagnose only, change nothing
bash fix-linux-speakers.sh # apply the safe fixes (it asks before anything needs sudo)
If you want to understand why a sleeping amplifier looks exactly like working audio to every tool on the system — and the one place you can look to tell the difference — read on.
The first lie: a perfect signal into silence
The machine is an HP Envy x360 15-ey0xxx running Linux Mint. First stop, the usual suspects. The driver was loaded, the card was detected, and PipeWire was running — but the default sink was muted at 40%. Unmute, set 75%, play a test tone. Still nothing.
So I tried to prove whether audio was actually flowing. I played a 660 Hz tone and, at the same time, recorded the audio sink’s own monitor — the loopback of whatever the sink is playing — then measured the captured waveform:
SINK=$(pactl get-default-sink)
parecord --device="${SINK}.monitor" --file-format=wav /tmp/verify.wav &
speaker-test -t sine -f 660 -l 1 -c 2
peak = 26215 (80.0% of full scale)
rms = 11924 (36.4% of full scale)
RESULT: SIGNAL PRESENT
Eighty percent amplitude. A clean, strong sine wave. By every number on the screen, audio was playing. And the room was silent.
That capture is real — but it’s a measurement of the sink, a software object inside PipeWire. It proves the audio pipeline carried sound right up to the edge of the operating system. It says exactly nothing about whether the physical amplifier turned that signal into cone movement. I’d measured success at the precise layer where the bug wasn’t.
What’s actually between the OS and the cones
These speakers aren’t wired straight to the audio codec. HP put two Cirrus Logic CS35L41 “smart amplifiers” in the chain — separate chips on an I²C bus that have to be powered up, configured, and explicitly told to pass audio by a kernel driver. This is why it worked on Windows: HP ships a mature driver that knows how to wake and hold these amps. On Linux, that responsibility falls to the snd_hda_scodec_cs35l41 driver, and the wiring is model-specific.
Watching the amplifiers’ runtime power state during playback told the real story:
for i in 1 2 3 4 5; do
sleep 0.5
echo "amp0=$(cat /sys/bus/i2c/devices/i2c-CSC3551:00-cs35l41-hda.0/power/runtime_status) \
amp1=$(cat /sys/bus/i2c/devices/i2c-CSC3551:00-cs35l41-hda.1/power/runtime_status)"
done
amp0=suspended amp1=suspended
amp0=suspended amp1=suspended
amp0=suspended amp1=suspended
Audio playing, sink showing signal, and both amplifiers suspended the whole time. The signal reached the last software inch of the system and then hit two chips that were powered down. Silence, with a green light on every dial.
Eliminating the software, layer by layer
Before blaming the driver I had to rule out everything I could actually change. The right order is cheap-and-reversible first:
- Sink muted / low volume — unmuted, set to 70%.
- Wrong output port — confirmed the active port was
Speaker, not headphones. - Aggressive power saving wedging the amp —
options snd_hda_intel power_save=0in/etc/modprobe.d/. - Realtek
Auto-Mute Mode— this one was genuinelyEnabled. On Realtek ALC245 codecs, Auto-Mute cuts the speakers when it thinks a headphone is plugged in, and it can latch on a phantom detection. Disabled it at the codec level withamixer.
After each fix: still silent. Then a clean reboot with every one of those changes persisted — and still silent. That reboot is the important data point. Once the entire software stack is in a known-good state and the speakers are still dead, the software is exonerated. The fault is in the one thing I hadn’t changed: the driver.
The fix: a kernel that knows this laptop
The CS35L41 driver has been getting model-by-model fixes for HP’s AMD laptops across kernel releases. Mint was on 6.8, where the driver could detect and power the amps but couldn’t fully engage their output stage on this specific board. The fix was a newer kernel that carries the later patches:
sudo apt install --install-recommends linux-generic-hwe-24.04
sudo reboot
(One snag worth flagging: the new kernel’s install choked on an unrelated third-party DKMS module — a USB Wi-Fi driver — that wouldn’t compile against the newer kernel. The kernel itself installed fine; I removed the orphaned module with sudo dkms remove, ran sudo dpkg --configure -a, and the package state was clean again. If a kernel install fails on a DKMS build error, check which module failed before assuming the kernel is the problem — it’s usually some out-of-tree driver, not the kernel.)
Reboot into 6.17, play anything, and the speakers work. Watching the amplifiers now, they flip from suspended to active the instant audio starts — which is exactly what was never happening before.
The takeaway
The speakers were never broken, and “missing driver” was the wrong frame — the driver was present, it just couldn’t drive this hardware. The thing that cost the most time wasn’t the fix; it was the 80%-amplitude recording that confidently told me audio was playing. A measurement is only as trustworthy as its distance from the actual failure, and a sink monitor sits one critical chip away from the speaker cone.
So the debugging move that mattered was refusing to trust the green number and instead watching the power state of the last physical component in the chain. When a system insists everything works and the real world disagrees, find the lowest layer you can directly observe — runtime_status on the amplifier, not amplitude on the sink — and believe that one instead.
If you’re hitting this — no sound from internal speakers on an HP Envy/Pavilion (or similar Cirrus CS35L41 + Realtek ALC245 laptop), working fine on Windows — the short version: it’s almost certainly not your speakers and not a missing driver. Check for Auto-Mute Mode at the codec level first, then upgrade to a kernel new enough to wake the smart amplifiers. On Ubuntu/Mint that’s the HWE kernel; on a rolling distro, just the latest stable.
Newsletter
Liked this? Get the next one.
One essay or short note every other week — privacy-first software, AI, security, and the occasional dispatch from the trail. No filler.
More writing
The Flagship Encryption Feature That Never Actually Turned On
The eighth round of a self-pentest found MoodHaven's flagship 'encrypted at rest' feature had never engaged on any build — then a custom attack tool and a fix-the-fixes round closed the campaign. Part 3 of a four-part series.
ReadMy First Metasploit Module to Land: an Audiobookshelf Auth Bypass
CVE-2025-25205 is an unauthenticated auth bypass in Audiobookshelf caused by matching a whitelist regex against the full request URL — query string and all. Here's the bug, the crash-safe detection module I wrote for it, and what it took to get my first PR merged into the Metasploit Framework.
ReadAttacking the AI Stack: Teaching garak to Smuggle Exploits Through a Model
The LiteLLM scanner attacked the gateway. These two garak probes attack the layer above it — getting the model itself to hand you a shell command or a Mongo operator, on the bet that something downstream will run it. Here's how the probes work, and why the detectors are the hard part.
Read