apm(4/arm64) merely provides an all zero/unknown stub for those values,
e.g. apm(8) output is useless.
Hardware sensors however provide the information:
$ sysctl hw.sensors
hw.sensors.rktemp0.temp0=32.22 degC (CPU)
hw.sensors.rktemp0.temp1=33.89 degC (GPU)
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)
Diff below simply copies them over using apm_setinfohook()
(I've looked at sys/arch/loongson/dev/kb3310.c which does the same):
$ apm
Battery state: high, 58% remaining, 259 minutes life estimate
A/C adapter state: not known
Performance adjustment mode: auto (408 MHz)
Feedback? OK?
Index: dev/fdt/cwfg.c
===================================================================
RCS file: /cvs/src/sys/dev/fdt/cwfg.c,v
retrieving revision 1.1
diff -u -p -r1.1 cwfg.c
--- dev/fdt/cwfg.c 10 Jun 2020 17:51:21 -0000 1.1
+++ dev/fdt/cwfg.c 20 Mar 2021 23:43:13 -0000
@@ -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,18 @@ struct cfdriver cwfg_cd = {
NULL, "cwfg", DV_DULL
};
+int cwfg_apminfo(struct apm_power_info *info);
+#if NAPM > 0
+struct apm_power_info cwfg_power;
+
+int
+cwfg_apminfo(struct apm_power_info *info)
+{
+ bcopy(&cwfg_power, info, sizeof(*info));
+ return 0;
+}
+#endif
+
int
cwfg_match(struct device *parent, void *match, void *aux)
{
@@ -202,6 +217,12 @@ cwfg_attach(struct device *parent, struc
sensor_task_register(sc, cwfg_update_sensors, 5);
+#if NAPM > 0
+ /* make sure we have the apm state initialized before apm attaches */
+ cwfg_update_sensors(sc);
+ apm_setinfohook(cwfg_apminfo);
+#endif
+
printf("\n");
}
@@ -324,6 +345,7 @@ cwfg_update_sensors(void *arg)
uint32_t vcell, rtt, tmp;
uint8_t val;
int error, n;
+ u_char bat_percent;
if ((error = cwfg_lock(sc)) != 0)
return;
@@ -348,6 +370,7 @@ cwfg_update_sensors(void *arg)
if ((error = cwfg_read(sc, SOC_HI_REG, &val)) != 0)
goto done;
if (val != 0xff) {
+ bat_percent = val;
sc->sc_sensor[CWFG_SENSOR_SOC].value = val * 1000;
sc->sc_sensor[CWFG_SENSOR_SOC].flags &= ~SENSOR_FINVALID;
}
@@ -363,6 +386,14 @@ cwfg_update_sensors(void *arg)
sc->sc_sensor[CWFG_SENSOR_RTT].value = rtt;
sc->sc_sensor[CWFG_SENSOR_RTT].flags &= ~SENSOR_FINVALID;
}
+
+#if NAPM > 0
+ cwfg_power.battery_state = bat_percent > sc->sc_alert_level ?
+ APM_BATT_HIGH : APM_BATT_LOW;
+ cwfg_power.ac_state = APM_AC_UNKNOWN;
+ cwfg_power.battery_life = bat_percent;
+ cwfg_power.minutes_left = sc->sc_sensor[CWFG_SENSOR_RTT].value;
+#endif
done:
cwfg_unlock(sc);