diff options
author | kn <kn@cvs.openbsd.org> | 2021-03-25 12:18:28 +0000 |
---|---|---|
committer | kn <kn@cvs.openbsd.org> | 2021-03-25 12:18:28 +0000 |
commit | 1338b2ad9d6a63c67027a1dc78dd6b75e4227d8b (patch) | |
tree | 5942165f4885ce6e886d87799332971c06fddf48 | |
parent | 0c1414d5d2cf42314242a37f1f5623e6cab4624a (diff) |
Provide apm(4/arm64) with battery information
apm merely provides an all zero/unknown stub for those values, e.g. apm(8)
output is useless.
Hardware sensors however provide this information:
hw.sensors.cwfg0.volt0=3.76 VDC (battery voltage)
hw.sensors.cwfg0.raw0=259 (battery remaining minutes)
hw.sensors.cwfg0.percent0=58.00% (battery percent)
Make cwfg(4) copy those over using apm_setinfohook() for apm to show it:
Battery state: high, 58% remaining, 259 minutes life estimate
A/C adapter state: not known
Performance adjustment mode: auto (408 MHz)
In cwfg's update routine, to keep values coherent, always reset them to
zero/unknown and only set those that came from a valid reading.
Input OK jca
-rw-r--r-- | sys/dev/fdt/cwfg.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/sys/dev/fdt/cwfg.c b/sys/dev/fdt/cwfg.c index 1a690647f44..b08c56e26e1 100644 --- a/sys/dev/fdt/cwfg.c +++ b/sys/dev/fdt/cwfg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cwfg.c,v 1.2 2021/03/22 18:37:26 kn Exp $ */ +/* $OpenBSD: cwfg.c,v 1.3 2021/03/25 12:18:27 kn Exp $ */ /* $NetBSD: cwfg.c,v 1.1 2020/01/03 18:00:05 jmcneill Exp $ */ /*- * Copyright (c) 2020 Jared McNeill <jmcneill@invisible.ca> @@ -32,12 +32,15 @@ #include <sys/malloc.h> #include <sys/sensors.h> +#include <machine/apmvar.h> #include <machine/fdt.h> #include <dev/ofw/openfirm.h> #include <dev/i2c/i2cvar.h> +#include "apm.h" + #define VERSION_REG 0x00 #define VCELL_HI_REG 0x02 #define VCELL_HI_MASK 0x3f @@ -119,6 +122,22 @@ struct cfdriver cwfg_cd = { NULL, "cwfg", DV_DULL }; +#if NAPM > 0 +struct apm_power_info cwfg_power = { + .battery_state = APM_BATT_UNKNOWN, + .ac_state = APM_AC_UNKNOWN, + .battery_life = 0, + .minutes_left = -1, +}; + +int +cwfg_apminfo(struct apm_power_info *info) +{ + memcpy(info, &cwfg_power, sizeof(*info)); + return 0; +} +#endif + int cwfg_match(struct device *parent, void *match, void *aux) { @@ -202,6 +221,10 @@ cwfg_attach(struct device *parent, struct device *self, void *aux) sensor_task_register(sc, cwfg_update_sensors, 5); +#if NAPM > 0 + apm_setinfohook(cwfg_apminfo); +#endif + printf("\n"); } @@ -325,6 +348,15 @@ cwfg_update_sensors(void *arg) uint8_t val; int error, n; +#if NAPM > 0 + /* reset previous reads so apm(4) never gets stale values + * in case of transient cwfg_read() failures below */ + cwfg_power.battery_state = APM_BATT_UNKNOWN; + cwfg_power.ac_state = APM_AC_UNKNOWN; + cwfg_power.battery_life = 0; + cwfg_power.minutes_left = -1; +#endif + if ((error = cwfg_lock(sc)) != 0) return; @@ -350,6 +382,11 @@ cwfg_update_sensors(void *arg) if (val != 0xff) { sc->sc_sensor[CWFG_SENSOR_SOC].value = val * 1000; sc->sc_sensor[CWFG_SENSOR_SOC].flags &= ~SENSOR_FINVALID; +#if NAPM > 0 + cwfg_power.battery_state = val > sc->sc_alert_level ? + APM_BATT_HIGH : APM_BATT_LOW; + cwfg_power.battery_life = val; +#endif } /* RTT */ @@ -362,6 +399,9 @@ cwfg_update_sensors(void *arg) if (rtt != 0x1fff) { sc->sc_sensor[CWFG_SENSOR_RTT].value = rtt; sc->sc_sensor[CWFG_SENSOR_RTT].flags &= ~SENSOR_FINVALID; +#if NAPM > 0 + cwfg_power.minutes_left = rtt; +#endif } done: |