summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkn <kn@cvs.openbsd.org>2021-03-25 12:18:28 +0000
committerkn <kn@cvs.openbsd.org>2021-03-25 12:18:28 +0000
commit1338b2ad9d6a63c67027a1dc78dd6b75e4227d8b (patch)
tree5942165f4885ce6e886d87799332971c06fddf48
parent0c1414d5d2cf42314242a37f1f5623e6cab4624a (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.c42
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: