I'm trying to fix a minor annoyance on my x240: the speaker mute key LED-state is not respected at boot. Pressing the mute key will mute the speaker while the expected behavior is to unmute. The LED-state will remain out-of-sync until I run `mixerctl -t outputs.master.mute`.
I've managed to determine if the speaker is muted in the acpithinkpad(4) attach function by reading from the embedded controller. However, calling wskbd_set_mixervolume at this stage returns ENODEV. I assume the audio device has not been attached yet. I'm new to kernel development and therefore wonder if this approach makes sense. If true, is it possible to postpone a task to run once a certain device has attached? Any feedback would be appreciated. Index: acpithinkpad.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v retrieving revision 1.52 diff -u -p -r1.52 acpithinkpad.c --- acpithinkpad.c 5 May 2016 05:12:49 -0000 1.52 +++ acpithinkpad.c 12 Sep 2016 15:03:31 -0000 @@ -105,9 +105,12 @@ #define THINKPAD_NSENSORS 9 #define THINKPAD_NTEMPSENSORS 8 +#define THINKPAD_ECOFFSET_VOLUME 0x30 #define THINKPAD_ECOFFSET_FANLO 0x84 #define THINKPAD_ECOFFSET_FANHI 0x85 +#define THINKPAD_ECMASK_VOLUME_MUTE 0x40 + #define THINKPAD_ADAPTIVE_MODE_HOME 1 #define THINKPAD_ADAPTIVE_MODE_FUNCTION 3 @@ -252,6 +255,7 @@ thinkpad_attach(struct device *parent, s { struct acpithinkpad_softc *sc = (struct acpithinkpad_softc *)self; struct acpi_attach_args *aa = aux; + uint8_t vol = 0; sc->sc_acpi = (struct acpi_softc *)parent; sc->sc_devnode = aa->aaa_node; @@ -282,6 +286,16 @@ thinkpad_attach(struct device *parent, s ws_get_param = thinkpad_get_param; ws_set_param = thinkpad_set_param; } + +#if NAUDIO > 0 && NWSKBD > 0 + if (sc->sc_acpi->sc_ec != NULL) { + acpiec_read(sc->sc_acpi->sc_ec, THINKPAD_ECOFFSET_VOLUME, + 1, &vol); + if ((vol & THINKPAD_ECMASK_VOLUME_MUTE) + == THINKPAD_ECMASK_VOLUME_MUTE) + wskbd_set_mixervolume(0, 1); + } +#endif /* Run thinkpad_hotkey on button presses */ aml_register_notify(sc->sc_devnode, aa->aaa_dev,