Module Name:    src
Committed By:   macallan
Date:           Wed Oct 31 05:46:49 UTC 2012

Modified Files:
        src/sys/arch/macppc/dev: smartbat.c

Log Message:
implement limits and support event monitoring
now emergency shutdown on low battery works


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/macppc/dev/smartbat.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/macppc/dev/smartbat.c
diff -u src/sys/arch/macppc/dev/smartbat.c:1.12 src/sys/arch/macppc/dev/smartbat.c:1.13
--- src/sys/arch/macppc/dev/smartbat.c:1.12	Tue Sep 18 04:36:25 2012
+++ src/sys/arch/macppc/dev/smartbat.c	Wed Oct 31 05:46:49 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: smartbat.c,v 1.12 2012/09/18 04:36:25 macallan Exp $ */
+/*	$NetBSD: smartbat.c,v 1.13 2012/10/31 05:46:49 macallan Exp $ */
 
 /*-
  * Copyright (c) 2007 Michael Lorenz
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smartbat.c,v 1.12 2012/09/18 04:36:25 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smartbat.c,v 1.13 2012/10/31 05:46:49 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -91,6 +91,8 @@ static void smartbat_attach(device_t, de
 static int smartbat_match(device_t, cfdata_t, void *);
 static void smartbat_setup_envsys(struct smartbat_softc *);
 static void smartbat_refresh(struct sysmon_envsys *, envsys_data_t *);
+static void smartbat_get_limits(struct sysmon_envsys *, envsys_data_t *,
+    sysmon_envsys_lim_t *, uint32_t *);
 static void smartbat_refresh_ac(struct sysmon_envsys *, envsys_data_t *);
 static void smartbat_poll(void *);
 static int smartbat_update(struct smartbat_softc *, int);
@@ -212,8 +214,14 @@ smartbat_setup_envsys(struct smartbat_so
 	sc->sc_bat_sensor[BAT_CHARGING].value_cur = TRUE;
 	sc->sc_bat_sensor[BAT_CHARGING].state = ENVSYS_SVALID;
 
-	for (i = 0; i < BAT_NSENSORS; i++) {
+	for (i = 0; i < BAT_NSENSORS; i++)
 		sc->sc_bat_sensor[i].flags = ENVSYS_FMONNOTSUPP;
+
+	sc->sc_bat_sensor[BAT_CHARGE].flags =
+	    ENVSYS_FMONLIMITS | ENVSYS_FPERCENT | ENVSYS_FVALID_MAX;
+	sc->sc_bat_sensor[BAT_CHARGE_STATE].flags = ENVSYS_FMONSTCHANGED;
+
+	for (i = 0; i < BAT_NSENSORS; i++) {
 		if (sysmon_envsys_sensor_attach(sc->sc_bat_sme,
 						&sc->sc_bat_sensor[i])) {
 			sysmon_envsys_destroy(sc->sc_bat_sme);
@@ -225,6 +233,8 @@ smartbat_setup_envsys(struct smartbat_so
 	sc->sc_bat_sme->sme_cookie = sc;
 	sc->sc_bat_sme->sme_refresh = smartbat_refresh;
 	sc->sc_bat_sme->sme_class = SME_CLASS_BATTERY;
+	sc->sc_bat_sme->sme_flags = SME_POLL_ONLY | SME_INIT_REFRESH;
+	sc->sc_bat_sme->sme_get_limits = smartbat_get_limits;
 
 	if (sysmon_envsys_register(sc->sc_bat_sme)) {
 		aprint_error("%s: unable to register with sysmon\n",
@@ -237,12 +247,14 @@ static void
 smartbat_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
 {
 	struct smartbat_softc *sc = sme->sme_cookie;
-	int which = edata->sensor, present;
+	int which = edata->sensor, present, ch;
 
 	smartbat_update(sc, 0);
 	present = (sc->sc_flags & PMU_PWR_BATT_PRESENT) != 0;
+	ch = sc->sc_charge * 100 / sc->sc_max_charge;
 
 	if (present) {
+		edata->state = ENVSYS_SVALID;
 		switch (which) {
 		case BAT_PRESENT:
 			edata->value_cur = present;
@@ -258,6 +270,14 @@ smartbat_refresh(struct sysmon_envsys *s
 			break;
 		case BAT_CHARGE:
 			edata->value_cur = sc->sc_charge * 1000;
+			edata->value_max = sc->sc_max_charge * 1000;
+			if (ch < 6) {
+				edata->state = ENVSYS_SCRITICAL;
+			} else if (ch < 11) {
+				edata->state = ENVSYS_SCRITUNDER;
+			} else if (ch < 20) {
+				edata->state = ENVSYS_SWARNUNDER;
+			}
 			break;
 		case BAT_CHARGING:
 			if ((sc->sc_flags & PMU_PWR_BATT_CHARGING) &&
@@ -268,17 +288,15 @@ smartbat_refresh(struct sysmon_envsys *s
 			break;
 		case BAT_CHARGE_STATE:
 			{
-				int ch = sc->sc_charge * 100 / 
-				    sc->sc_max_charge;
 				if (ch < 6) {
 					edata->value_cur = 
 					    ENVSYS_BATTERY_CAPACITY_CRITICAL;
-				} else if (ch < 11) {
+				} else if (ch < 10) {
 					edata->value_cur = 
-					    ENVSYS_BATTERY_CAPACITY_WARNING;
+					    ENVSYS_BATTERY_CAPACITY_LOW;
 				} else if (ch < 20) {
 					edata->value_cur = 
-					    ENVSYS_BATTERY_CAPACITY_LOW;
+					    ENVSYS_BATTERY_CAPACITY_WARNING;
 				} else {
 					edata->value_cur = 
 					    ENVSYS_BATTERY_CAPACITY_NORMAL;
@@ -289,7 +307,6 @@ smartbat_refresh(struct sysmon_envsys *s
 			edata->value_cur = (sc->sc_flags & PMU_PWR_BATT_FULL);
 			break;
 		}
-		edata->state = ENVSYS_SVALID;
 	} else {
 		/* battery isn't there */
 		switch (which) {
@@ -313,6 +330,21 @@ smartbat_refresh(struct sysmon_envsys *s
 }
 
 static void
+smartbat_get_limits(struct sysmon_envsys *sme, envsys_data_t *edata,
+    sysmon_envsys_lim_t *limits, uint32_t *props)
+{
+	struct smartbat_softc *sc = sme->sme_cookie;
+
+	if (edata->sensor != BAT_CHARGE)
+		return;
+
+	limits->sel_critmin = sc->sc_max_charge * 1000 / 100 * 10; /* 20% */
+	limits->sel_warnmin = sc->sc_max_charge * 1000 / 100 * 20; /* 10% */
+
+	*props |= PROP_BATTCAP | PROP_BATTWARN | PROP_DRIVER_LIMITS;
+}
+
+static void
 smartbat_refresh_ac(struct sysmon_envsys *sme, envsys_data_t *edata)
 {
 	struct smartbat_softc *sc = sme->sme_cookie;
@@ -321,10 +353,12 @@ smartbat_refresh_ac(struct sysmon_envsys
 	smartbat_update(sc, 0);
 	switch (which) {
 		case BAT_AC_PRESENT:
-			edata->value_cur = (sc->sc_flags & PMU_PWR_AC_PRESENT);
+			edata->value_cur =
+			    ((sc->sc_flags & PMU_PWR_AC_PRESENT) != 0);
 			edata->state = ENVSYS_SVALID;
 			break;
 		default:
+			edata->value_cur = 0;
 			edata->state = ENVSYS_SINVALID;
 	}
 }
@@ -416,7 +450,7 @@ smartbat_poll(void *cookie)
 		return;
 
 	sc->sc_oflags = sc->sc_flags & PMU_PWR_AC_PRESENT;
-
+	sc->sc_ac_sensor[0].value_cur = sc->sc_oflags ? 1 : 0;
 	sysmon_pswitch_event(&sc->sc_sm_acpower, 
 	    sc->sc_oflags ? PSWITCH_EVENT_PRESSED :
 	    PSWITCH_EVENT_RELEASED);

Reply via email to