asmc(4): Add support for backlight(9) interface

MFC after:	1 month
This commit is contained in:
Vladimir Kondratyev
2026-03-29 22:00:59 +03:00
parent 056e29070f
commit 5d7862fb99
4 changed files with 80 additions and 2 deletions
+10 -1
View File
@@ -79,7 +79,9 @@ On
systems, you can control the keyboard brightness by writing a value to systems, you can control the keyboard brightness by writing a value to
the the
.Va dev.asmc.%d.light.control .Va dev.asmc.%d.light.control
sysctl MIB. sysctl MIB or with
.Xr backlight 8
utility.
.Pp .Pp
The following sysctl MIBs contains the raw value returned by the left The following sysctl MIBs contains the raw value returned by the left
and right light sensors: and right light sensors:
@@ -143,8 +145,15 @@ dramatically reduce your hard drive's life span.
Do not rely solely on Do not rely solely on
the SMS to protect your hard drive: good care and common sense can the SMS to protect your hard drive: good care and common sense can
increase your hard drive's life. increase your hard drive's life.
.Sh FILES
.Bl -tag -width ".Pa /dev/backlight/asmc0" -compact
.It Pa /dev/backlight/asmc0
Keyboard
.Xr backlight 8
device node.
.Sh SEE ALSO .Sh SEE ALSO
.Xr ataidle 8 Pq Pa ports/sysutils/ataidle , .Xr ataidle 8 Pq Pa ports/sysutils/ataidle ,
.Xr backlight 8 ,
.Xr devd 8 , .Xr devd 8 ,
.Xr sysctl 8 .Xr sysctl 8
.Sh HISTORY .Sh HISTORY
+66
View File
@@ -58,6 +58,9 @@
#include <dev/acpica/acpivar.h> #include <dev/acpica/acpivar.h>
#include <dev/asmc/asmcvar.h> #include <dev/asmc/asmcvar.h>
#include <dev/backlight/backlight.h>
#include "backlight_if.h"
/* /*
* Device interface. * Device interface.
*/ */
@@ -66,6 +69,15 @@ static int asmc_attach(device_t dev);
static int asmc_detach(device_t dev); static int asmc_detach(device_t dev);
static int asmc_resume(device_t dev); static int asmc_resume(device_t dev);
/*
* Backlight interface.
*/
static int asmc_backlight_update_status(device_t dev,
struct backlight_props *props);
static int asmc_backlight_get_status(device_t dev,
struct backlight_props *props);
static int asmc_backlight_get_info(device_t dev, struct backlight_info *info);
/* /*
* SMC functions. * SMC functions.
*/ */
@@ -581,6 +593,12 @@ static device_method_t asmc_methods[] = {
DEVMETHOD(device_attach, asmc_attach), DEVMETHOD(device_attach, asmc_attach),
DEVMETHOD(device_detach, asmc_detach), DEVMETHOD(device_detach, asmc_detach),
DEVMETHOD(device_resume, asmc_resume), DEVMETHOD(device_resume, asmc_resume),
/* Backlight interface */
DEVMETHOD(backlight_update_status, asmc_backlight_update_status),
DEVMETHOD(backlight_get_status, asmc_backlight_get_status),
DEVMETHOD(backlight_get_info, asmc_backlight_get_info),
DEVMETHOD_END DEVMETHOD_END
}; };
@@ -609,6 +627,7 @@ static unsigned int light_control = 0;
ACPI_PNP_INFO(asmc_ids); ACPI_PNP_INFO(asmc_ids);
DRIVER_MODULE(asmc, acpi, asmc_driver, NULL, NULL); DRIVER_MODULE(asmc, acpi, asmc_driver, NULL, NULL);
MODULE_DEPEND(asmc, acpi, 1, 1, 1); MODULE_DEPEND(asmc, acpi, 1, 1, 1);
MODULE_DEPEND(asmc, backlight, 1, 1, 1);
static const struct asmc_model * static const struct asmc_model *
asmc_match(device_t dev) asmc_match(device_t dev)
@@ -800,6 +819,13 @@ asmc_attach(device_t dev)
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE,
dev, 0, model->smc_light_control, "I", dev, 0, model->smc_light_control, "I",
"Keyboard backlight brightness control"); "Keyboard backlight brightness control");
sc->sc_kbd_bkl = backlight_register("asmc", dev);
if (sc->sc_kbd_bkl == NULL) {
device_printf(dev, "Can not register backlight\n");
ret = ENXIO;
goto err;
}
} }
if (model->smc_sms_x == NULL) if (model->smc_sms_x == NULL)
@@ -882,6 +908,9 @@ asmc_detach(device_t dev)
{ {
struct asmc_softc *sc = device_get_softc(dev); struct asmc_softc *sc = device_get_softc(dev);
if (sc->sc_kbd_bkl != NULL)
backlight_destroy(sc->sc_kbd_bkl);
if (sc->sc_sms_tq) { if (sc->sc_sms_tq) {
taskqueue_drain(sc->sc_sms_tq, &sc->sc_sms_task); taskqueue_drain(sc->sc_sms_tq, &sc->sc_sms_task);
taskqueue_free(sc->sc_sms_tq); taskqueue_free(sc->sc_sms_tq);
@@ -1739,6 +1768,7 @@ static int
asmc_mbp_sysctl_light_control(SYSCTL_HANDLER_ARGS) asmc_mbp_sysctl_light_control(SYSCTL_HANDLER_ARGS)
{ {
device_t dev = (device_t)arg1; device_t dev = (device_t)arg1;
struct asmc_softc *sc = device_get_softc(dev);
uint8_t buf[2]; uint8_t buf[2];
int error; int error;
int v; int v;
@@ -1750,6 +1780,7 @@ asmc_mbp_sysctl_light_control(SYSCTL_HANDLER_ARGS)
if (v < 0 || v > 255) if (v < 0 || v > 255)
return (EINVAL); return (EINVAL);
light_control = v; light_control = v;
sc->sc_kbd_bkl_level = v * 100 / 255;
buf[0] = light_control; buf[0] = light_control;
buf[1] = 0x00; buf[1] = 0x00;
asmc_key_write(dev, ASMC_KEY_LIGHTVALUE, buf, sizeof(buf)); asmc_key_write(dev, ASMC_KEY_LIGHTVALUE, buf, sizeof(buf));
@@ -1817,3 +1848,38 @@ asmc_wol_sysctl(SYSCTL_HANDLER_ARGS)
return (0); return (0);
} }
static int
asmc_backlight_update_status(device_t dev, struct backlight_props *props)
{
struct asmc_softc *sc = device_get_softc(dev);
uint8_t buf[2];
sc->sc_kbd_bkl_level = props->brightness;
light_control = props->brightness * 255 / 100;
buf[0] = light_control;
buf[1] = 0x00;
asmc_key_write(dev, ASMC_KEY_LIGHTVALUE, buf, sizeof(buf));
return (0);
}
static int
asmc_backlight_get_status(device_t dev, struct backlight_props *props)
{
struct asmc_softc *sc = device_get_softc(dev);
props->brightness = sc->sc_kbd_bkl_level;
props->nlevels = 0;
return (0);
}
static int
asmc_backlight_get_info(device_t dev, struct backlight_info *info)
{
info->type = BACKLIGHT_TYPE_KEYBOARD;
strlcpy(info->name, "Apple MacBook Keyboard", BACKLIGHTMAXNAMELENGTH);
return (0);
}
+2
View File
@@ -51,6 +51,8 @@ struct asmc_softc {
struct taskqueue *sc_sms_tq; struct taskqueue *sc_sms_tq;
struct task sc_sms_task; struct task sc_sms_task;
uint8_t sc_sms_intr_works; uint8_t sc_sms_intr_works;
struct cdev *sc_kbd_bkl;
uint32_t sc_kbd_bkl_level;
}; };
/* /*
+2 -1
View File
@@ -1,6 +1,7 @@
.PATH: ${SRCTOP}/sys/dev/asmc .PATH: ${SRCTOP}/sys/dev/asmc
KMOD= asmc KMOD= asmc
SRCS= asmc.c opt_acpi.h opt_asmc.h acpi_if.h bus_if.h device_if.h SRCS= asmc.c opt_acpi.h opt_asmc.h
SRCS+= acpi_if.h backlight_if.h bus_if.h device_if.h
.include <bsd.kmod.mk> .include <bsd.kmod.mk>