The Mute LED That Wouldn't Light: Chasing a Reddit Hack Into a Kernel Patch
DEV Community

The Mute LED That Wouldn't Light: Chasing a Reddit Hack Into a Kernel Patch

So this one's not about hid_guard. While that saga sits in maintainer-review limbo, I got sidetracked by something smaller. The fix itself is simple and genuinely nothing to look at. But I like how I got there, because it's a pretty honest example of what "just Google it" actually looks like when the first working answer still bugs you. TL;DR: My laptop's mute LED didn't work. Reddit had a working hack. That hack bugged me enough that I went and found the real fix in the kernel source instead, and got it merged upstream. A week later, that same digging paid off again, this time on someone else's laptop had the identical bug. The bug My laptop: an HP Omen 16-wd0xxx. The mute LED: the light that's supposed to tell you the speakers are muted; just didn't. Hit mute, audio actually muted, LED sat there unlit. Debugging - Software or hardware? Booted Windows and the LED worked fine there. Not dead hardware. - Input or output? Ran evtest on the keyboard, compared the mute key's event against Caps Lock (known-good). Identical shape, and audio was genuinely muting. So the break was narrow: mute state happened, the LED just never got told. - Also Checked /sys/class/leds/ . Nothing. No generic LED class device existed for it - whatever drove this LED lived outside the usual abstraction entirely. Reddit had the answer (sort of) People were grepping /proc/asound/card*/codec* to identify their codec, then writing raw hex values straight into codec registers to flip the LED by hand. I tried it and it worked immediately. I wrapped it in a shell script, run by a systemd service on boot and on every mute-state change. It didn't sit right, though. I was reaching into codec registers from userspace on every boot, for something that felt like a solved problem at the driver level. HP ships this exact codec across a dozen laptop variants, no way I was the first to hit this. If a real fix existed, it almost certainly already lived upstream. That's what sent me into the kernel source instead of calling the Reddit fix "good enough." Going and looking for the real one cat /proc/asound/card#/codec#* confirmed the codec (Realtek ALC245) and gave me my PCI subsystem ID (SSID). Grepping sound/hda for both turned up two candidate files: alc260.c (older, clearly a previous generation) and alc269.c (a huge, actively maintained table with current HP/Acer/Asus models). The second was obviously the one still being kept up to date. That file holds SND_PCI_QUIRK entries: a lookup from a laptop's PCI SSID to the fixup its codec needs. HP alone has close to a hundred entries, since every OEM wires the same Realtek codec slightly differently. Verifying the mechanism before trusting a name: - Found two hda-verb commands for this LED: select coefficient0x0b , write0x7778 (on) or0x7774 (off). - With no fixup loaded, read that coefficient before and after toggling mute - identical both times. Inert, as expected. - Forced it by hand: wrote 0x7778 , LED lit instantly.0x7774 turned it off. Confirmed - that coefficient drives the LED, independent of any fixup. With the mechanism confirmed, I tried ALC245_FIXUP_HP_MUTE_LED_V2_COEFBIT first, assuming the newer-looking name meant a better match. LED lit, but dim and half-toggled. Swapped to V1 - matched exactly what I'd confirmed by hand. (IK I should've read the actual implementation first, which I eventually did, after, to better understand the why.) The real difference: V1 and V2 target entirely different coefficient bits. Testing it (and doing it wrong first) Actually testing a fixup meant running a kernel with that code in it, not just compiling it somewhere and hoping. I'm on Arch (btw), so there's no packaged kernel with room to slot in an out-of-tree quirk building linux_mainline myself was the only option. First attempt, I tried getting the rebuilt module into my already-running kernel instead of rebooting into the new one. Didn't work, and it took a bit of failing to figure out why. Noob mistake so did a full build and reboot, every time... The fix itself + SND_PCI_QUIRK(0x103c, 0x8ba9, "HP Omen 16-wd0xxx", ALC245_FIXUP_HP_MUTE_LED_V1_COEFBIT), All that investigation, for a single table entry; but the line only works because of everything above it. Slight oversight I'd dropped my entry "roughly where it seemed relevant" instead of checking that entries are sorted by PCI device ID. Not a logic bug, just a convention I'd missed. Fixed it, sent v2. The Maintainer Takashi Iwai applied it. lore.kernel.org/linux-sound/87h5***************@suse.de And then someone else needed it too A week later, kernel.org Bugzilla bug #221982 showed up: same symptom, on a completely different laptop; an HP Victus Gaming 15-fa1xxx to be precise, SSID 103c:8bb1 . Same ALC245 codec, same missing quirk-table entry. The reporter had already narrowed the codec down himself. This time the fix was purely mechanical. He tested it on his own hardware before I sent the patch. The maintainer applied it the same day. That one landed differently for me. The previous fix solved my own problem - satisfying, but self-contained. This one was something I'd learned a week earlier, from fixing my own laptop, turning around and fixing a stranger's, without him having to do any of the digging I did. That's the part that stuck: not the second patch itself, but that the process from the first one turned out to be useful to someone I've never met. None of this is a "major" patch. But the size was never the point, the point is the ick. That moment of "this works, but I don't like how" is what turned a five-minute Reddit fix into a kernel patch, and having that patch already in the tree is what turned someone else's bug report into a one-line fix instead of a fresh investigation. If I got a step wrong, tell me in the comments, I'll fix the post. Top comments (0)

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.