asmc: add sleep indicator LED control via sysctl

Add dev.asmc.0.sil sysctl to control the SIL LED via SMC keys
MSLD (duty/brightness) and MSLS (state latch, must be set
before re-enabling).

MFC After: 1 week

Reviewed by:	adrian
Differential Revision:	https://reviews.freebsd.org/D58865
This commit is contained in:
Abdelkader Boudih committed 2026-09-06 20:47:44 +01:00
1 parent 0cf1002113
commit c6db719a54
2 files changed
+58 -2

No files matched your search

+45
View File
@@ -126,6 +126,7 @@ static int asmc_mbp_sysctl_light_right(SYSCTL_HANDLER_ARGS);
static int asmc_mbp_sysctl_light_control(SYSCTL_HANDLER_ARGS);
static int asmc_mbp_sysctl_light_left_10byte(SYSCTL_HANDLER_ARGS);
static int asmc_aupo_sysctl(SYSCTL_HANDLER_ARGS);
static int asmc_sil_sysctl(SYSCTL_HANDLER_ARGS);
static int asmc_key_getinfo(device_t, const char *, uint8_t *, char *);
@@ -939,6 +940,16 @@ asmc_init(device_t dev)
"Auto power-on after AC power loss (0=off, 1=on)");
}
/* Sleep Indicator LED (SIL) control via MSLD/MSLS keys. */
if (asmc_key_read(dev, ASMC_KEY_MSLD, buf, 1) == 0) {
SYSCTL_ADD_PROC(sysctlctx,
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
OID_AUTO, "sil",
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
dev, 0, asmc_sil_sysctl, "I",
"Sleep indicator LED (0=off, 1=on)");
}
sc->sc_nfan = asmc_fan_count(dev);
if (sc->sc_nfan > ASMC_MAXFANS) {
device_printf(dev,
@@ -2538,6 +2549,40 @@ asmc_aupo_sysctl(SYSCTL_HANDLER_ARGS)
return (0);
}
/* Sleep Indicator LED (SIL) control; see ASMC_KEY_MSLD/MSLS in asmcvar.h. */
static int
asmc_sil_sysctl(SYSCTL_HANDLER_ARGS)
{
device_t dev = (device_t)arg1;
uint8_t msld;
int val, error;
if (asmc_key_read(dev, ASMC_KEY_MSLD, &msld, 1) != 0)
return (EIO);
/* MSLD 0xff means off, anything else means on */
val = (msld != 0xff) ? 1 : 0;
error = sysctl_handle_int(oidp, &val, 0, req);
if (error != 0 || req->newptr == NULL)
return (error);
if (val != 0) {
/* Turn on: unlatch MSLS first, then set MSLD duty */
uint8_t msls = 0x01;
if (asmc_key_write(dev, ASMC_KEY_MSLS, &msls, 1) != 0)
return (EIO);
msld = 0x01;
} else {
/* Turn off: just set MSLD to 0xff */
msld = 0xff;
}
if (asmc_key_write(dev, ASMC_KEY_MSLD, &msld, 1) != 0)
return (EIO);
return (0);
}
static int
asmc_backlight_update_status(device_t dev, struct backlight_props *props)
{
+13 -2
View File
@@ -175,9 +175,20 @@ struct asmc_softc {
#define ASMC_KEY_FANSAFESPEED0 "F0Sf" /* RO; 2 bytes */
/*
* Clamshell.
* Sleep Indicator LED (SIL).
*
* MSLD controls the duty cycle of the front-panel sleep indicator LED.
* 0x00 = LED at idle brightness, 0xff = LED fully off.
* MSLS is the SIL state latch — must be written to 0x01 before MSLD
* can re-enable the LED after it has been turned off.
*
* Protocol: OFF = write MSLD 0xff
* ON = write MSLS 0x01, then write MSLD 0x01
*
* Present on all Intel Macs with a sleep indicator (laptops + Mac Mini).
*/
#define ASMC_KEY_CLAMSHELL "MSLD" /* RO; 1 byte */
#define ASMC_KEY_MSLD "MSLD" /* RW; 1 byte, SIL duty */
#define ASMC_KEY_MSLS "MSLS" /* RW; 1 byte, SIL state latch */
/*
* Auto power-on after AC power loss (AUPO).