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,