You are not logged in.

#1 2023-03-25 22:32:41

VDmvKcW9JamBSir5fNfehqpG
Member
From: Earth
Registered: 2019-12-30
Posts: 63

[SOLVED] Possible to make mute LEDs correspond to active interface?

I just got a thinkpad T580. It has status LEDs that are meant to indicate whether the device is muted: one for audio output and one for the microphone. I am using Pipewire with Wireplumber. I have found many people complaining about the LEDs not working at all, but for me they mostly work out of the box. However, the status of the LEDs always corresponds to the status of the built in analog stereo interface. This means that they are accurate when using the internal speakers and microphone or a 3.5mm headset, but not if I use audio on an external display or Bluetooth headphones. I almost always use my Bluetooth headphones and essentially have my laptop's internal speakers permanently muted, so having the LEDs only indicate the status of the built in interface is not useful to me. I would like to have them indicate the status of whatever device is currently active. I could write a script to do that, but that seems unnecessarily janky. Is this behavior configurable?

Last edited by VDmvKcW9JamBSir5fNfehqpG (2023-03-27 19:25:36)

Offline

#2 2023-03-26 05:00:27

dimich
Member
From: Kharkiv, Ukraine
Registered: 2009-11-03
Posts: 478

Re: [SOLVED] Possible to make mute LEDs correspond to active interface?

Check what LEDs are present in the system and what triggers are configured for each:

for i in /sys/class/leds/*; do echo "$i:"; cat "$i/trigger"; echo; done

Offline

#3 2023-03-26 07:52:21

VDmvKcW9JamBSir5fNfehqpG
Member
From: Earth
Registered: 2019-12-30
Posts: 63

Re: [SOLVED] Possible to make mute LEDs correspond to active interface?

/sys/class/leds/input3::capslock:
none usb-gadget usb-host rc-feedback kbd-scrolllock kbd-numlock [kbd-capslock] kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock AC-online BAT0-charging-or-full BAT0-charging BAT0-full BAT0-charging-blink-full-solid disk-activity disk-read disk-write ide-disk mtd nand-disk cpu cpu0 cpu1 cpu2 cpu3 cpu4 cpu5 cpu6 cpu7 panic rfkill-any rfkill-none audio-mute audio-micmute ucsi-source-psy-USBC000:001-online phy0rx phy0tx phy0assoc phy0radio rfkill1 ucsi-source-psy-USBC000:002-online bluetooth-power rfkill18 hci0-power rfkill27

/sys/class/leds/input3::numlock:
none usb-gadget usb-host rc-feedback kbd-scrolllock [kbd-numlock] kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock AC-online BAT0-charging-or-full BAT0-charging BAT0-full BAT0-charging-blink-full-solid disk-activity disk-read disk-write ide-disk mtd nand-disk cpu cpu0 cpu1 cpu2 cpu3 cpu4 cpu5 cpu6 cpu7 panic rfkill-any rfkill-none audio-mute audio-micmute ucsi-source-psy-USBC000:001-online phy0rx phy0tx phy0assoc phy0radio rfkill1 ucsi-source-psy-USBC000:002-online bluetooth-power rfkill18 hci0-power rfkill27

/sys/class/leds/input3::scrolllock:
none usb-gadget usb-host rc-feedback [kbd-scrolllock] kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock AC-online BAT0-charging-or-full BAT0-charging BAT0-full BAT0-charging-blink-full-solid disk-activity disk-read disk-write ide-disk mtd nand-disk cpu cpu0 cpu1 cpu2 cpu3 cpu4 cpu5 cpu6 cpu7 panic rfkill-any rfkill-none audio-mute audio-micmute ucsi-source-psy-USBC000:001-online phy0rx phy0tx phy0assoc phy0radio rfkill1 ucsi-source-psy-USBC000:002-online bluetooth-power rfkill18 hci0-power rfkill27

/sys/class/leds/phy0-led:
none usb-gadget usb-host rc-feedback kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock AC-online BAT0-charging-or-full BAT0-charging BAT0-full BAT0-charging-blink-full-solid disk-activity disk-read disk-write ide-disk mtd nand-disk cpu cpu0 cpu1 cpu2 cpu3 cpu4 cpu5 cpu6 cpu7 panic rfkill-any rfkill-none audio-mute audio-micmute ucsi-source-psy-USBC000:001-online phy0rx phy0tx phy0assoc [phy0radio] rfkill1 ucsi-source-psy-USBC000:002-online bluetooth-power rfkill18 hci0-power rfkill27

/sys/class/leds/platform::micmute:
none usb-gadget usb-host rc-feedback kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock AC-online BAT0-charging-or-full BAT0-charging BAT0-full BAT0-charging-blink-full-solid disk-activity disk-read disk-write ide-disk mtd nand-disk cpu cpu0 cpu1 cpu2 cpu3 cpu4 cpu5 cpu6 cpu7 panic rfkill-any rfkill-none audio-mute [audio-micmute] ucsi-source-psy-USBC000:001-online phy0rx phy0tx phy0assoc phy0radio rfkill1 ucsi-source-psy-USBC000:002-online bluetooth-power rfkill18 hci0-power rfkill27

/sys/class/leds/platform::mute:
none usb-gadget usb-host rc-feedback kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock AC-online BAT0-charging-or-full BAT0-charging BAT0-full BAT0-charging-blink-full-solid disk-activity disk-read disk-write ide-disk mtd nand-disk cpu cpu0 cpu1 cpu2 cpu3 cpu4 cpu5 cpu6 cpu7 panic rfkill-any rfkill-none [audio-mute] audio-micmute ucsi-source-psy-USBC000:001-online phy0rx phy0tx phy0assoc phy0radio rfkill1 ucsi-source-psy-USBC000:002-online bluetooth-power rfkill18 hci0-power rfkill27

/sys/class/leds/tpacpi::lid_logo_dot:
[none] usb-gadget usb-host rc-feedback kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock AC-online BAT0-charging-or-full BAT0-charging BAT0-full BAT0-charging-blink-full-solid disk-activity disk-read disk-write ide-disk mtd nand-disk cpu cpu0 cpu1 cpu2 cpu3 cpu4 cpu5 cpu6 cpu7 panic rfkill-any rfkill-none audio-mute audio-micmute ucsi-source-psy-USBC000:001-online phy0rx phy0tx phy0assoc phy0radio rfkill1 ucsi-source-psy-USBC000:002-online bluetooth-power rfkill18 hci0-power rfkill27

/sys/class/leds/tpacpi::power:
[none] usb-gadget usb-host rc-feedback kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock AC-online BAT0-charging-or-full BAT0-charging BAT0-full BAT0-charging-blink-full-solid disk-activity disk-read disk-write ide-disk mtd nand-disk cpu cpu0 cpu1 cpu2 cpu3 cpu4 cpu5 cpu6 cpu7 panic rfkill-any rfkill-none audio-mute audio-micmute ucsi-source-psy-USBC000:001-online phy0rx phy0tx phy0assoc phy0radio rfkill1 ucsi-source-psy-USBC000:002-online bluetooth-power rfkill18 hci0-power rfkill27

/sys/class/leds/tpacpi::standby:
[none] usb-gadget usb-host rc-feedback kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock AC-online BAT0-charging-or-full BAT0-charging BAT0-full BAT0-charging-blink-full-solid disk-activity disk-read disk-write ide-disk mtd nand-disk cpu cpu0 cpu1 cpu2 cpu3 cpu4 cpu5 cpu6 cpu7 panic rfkill-any rfkill-none audio-mute audio-micmute ucsi-source-psy-USBC000:001-online phy0rx phy0tx phy0assoc phy0radio rfkill1 ucsi-source-psy-USBC000:002-online bluetooth-power rfkill18 hci0-power rfkill27

/sys/class/leds/tpacpi::thinklight:
[none] usb-gadget usb-host rc-feedback kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock AC-online BAT0-charging-or-full BAT0-charging BAT0-full BAT0-charging-blink-full-solid disk-activity disk-read disk-write ide-disk mtd nand-disk cpu cpu0 cpu1 cpu2 cpu3 cpu4 cpu5 cpu6 cpu7 panic rfkill-any rfkill-none audio-mute audio-micmute ucsi-source-psy-USBC000:001-online phy0rx phy0tx phy0assoc phy0radio rfkill1 ucsi-source-psy-USBC000:002-online bluetooth-power rfkill18 hci0-power rfkill27

/sys/class/leds/tpacpi::thinkvantage:
[none] usb-gadget usb-host rc-feedback kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock AC-online BAT0-charging-or-full BAT0-charging BAT0-full BAT0-charging-blink-full-solid disk-activity disk-read disk-write ide-disk mtd nand-disk cpu cpu0 cpu1 cpu2 cpu3 cpu4 cpu5 cpu6 cpu7 panic rfkill-any rfkill-none audio-mute audio-micmute ucsi-source-psy-USBC000:001-online phy0rx phy0tx phy0assoc phy0radio rfkill1 ucsi-source-psy-USBC000:002-online bluetooth-power rfkill18 hci0-power rfkill27

scrolllock, phy0-led, standby, thinklight, and thinkvantage do not seem to physically exist on my system.

(Not related, but kinda neat that I can repurpose my power button LED into a disk activity indicator.)

Offline

#4 2023-03-27 03:22:05

dimich
Member
From: Kharkiv, Ukraine
Registered: 2009-11-03
Posts: 478

Re: [SOLVED] Possible to make mute LEDs correspond to active interface?

"audio-micmute" trigger is controlled by kernel's sound core. Bluetooth audio is provided by pulseaudio in userspace. So it should be a part of pulseaudio functionality to simulate micmute LED behavior.
I haven't found out-of-the-box solutions. Straightforwart way is to disable in-kernel trigger(echo none > /sys/class/leds/platform::micmute/trigger) and write a script which will subscribe to pulseaudio events (e.g. running `pactl subscribe`), read current mic mute state for default device on every change and write corresponding value to /sys/class/leds/platform::micmute/brightness.

Offline

#5 2023-03-27 16:08:37

VDmvKcW9JamBSir5fNfehqpG
Member
From: Earth
Registered: 2019-12-30
Posts: 63

Re: [SOLVED] Possible to make mute LEDs correspond to active interface?

OK, I guess that's what I'll have to do. I'm guessing the same is true for the speaker mute button?

Offline

#6 2023-03-27 19:22:19

dimich
Member
From: Kharkiv, Ukraine
Registered: 2009-11-03
Posts: 478

Re: [SOLVED] Possible to make mute LEDs correspond to active interface?

VDmvKcW9JamBSir5fNfehqpG wrote:

I'm guessing the same is true for the speaker mute button?

Yes, "audio-mute" trigger is controlled by kernel as well.

Offline

#7 2023-03-27 19:24:46

VDmvKcW9JamBSir5fNfehqpG
Member
From: Earth
Registered: 2019-12-30
Posts: 63

Re: [SOLVED] Possible to make mute LEDs correspond to active interface?

Well, that's annoying. But I know what I have to do now.

Offline

#8 Yesterday 22:37:28

Mat_A_Door
Member
Registered: 2025-12-27
Posts: 2

Re: [SOLVED] Possible to make mute LEDs correspond to active interface?

hello. In case anyone needs it, here is my code that subscribes to pulse audio and turns on/off the LED

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pulse/pulseaudio.h>

#define LED_PATH "/sys/class/leds/platform::micmute/brightness"

void set_LED_on() {
    system("echo 1 > " LED_PATH);
}

void set_LED_off() {
    system("echo 0 > " LED_PATH);
}

void sourceInfoCB(pa_context* c, const pa_source_info* i, int eol, void* data) {
    if (eol || !i) return;

    if (i->mute)
        set_LED_on();
    else
        set_LED_off();
}

void my_subscription_callback(pa_context *c,
                              pa_subscription_event_type_t t,
                              uint32_t idx,
                              void *userdata)
{
    pa_subscription_event_type_t facility =
        t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK;

    if (facility == PA_SUBSCRIPTION_EVENT_SOURCE) {
        pa_context_get_source_info_by_index(c, idx, sourceInfoCB, NULL);
    }
}

void context_state_cb(pa_context *c, void *userdata) {
    pa_context_state_t state = pa_context_get_state(c);

    if (state == PA_CONTEXT_READY) {
        pa_context_set_subscribe_callback(c, my_subscription_callback, NULL);

        pa_context_subscribe(
            c,
            PA_SUBSCRIPTION_MASK_SOURCE,
            NULL,
            NULL
        );
    }

    if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED) {
        exit(1);
    }
}

int main(int argc, char* argv[]) {
    pa_mainloop *ml = pa_mainloop_new();
    pa_mainloop_api *api = pa_mainloop_get_api(ml);

    pa_context *ctx = pa_context_new(api, "micmute-led");

    pa_context_set_state_callback(ctx, context_state_cb, NULL);
    pa_context_connect(ctx, NULL, PA_CONTEXT_NOFLAGS, NULL);

    set_LED_off();

    int ret;
    pa_mainloop_run(ml, &ret);

    pa_context_disconnect(ctx);
    pa_context_unref(ctx);
    pa_mainloop_free(ml);

    return 0;
}

compile it, don't forget to include the flag "-lpulse" when compiling with gcc

Then just add a service that runs the script once, and enable it with systemctl

Also, you might need to change the path of the LED file, or maybe even change the code that turns on/off the LED depending on your device. I'm on a thinkpad

Last edited by Mat_A_Door (Yesterday 22:38:22)

Offline

#9 Today 08:39:56

schard
Forum Moderator
From: Hannover
Registered: 2016-05-06
Posts: 2,527
Website

Re: [SOLVED] Possible to make mute LEDs correspond to active interface?

Mod note: Please refrain from necro-bumping. Closing this old thread.


Inofficial first vice president of the Rust Evangelism Strike Force

Offline

Board footer

Powered by FluxBB