add envsys support to acpi A/C adapter and batteries. This is still a work
in progress, much like the rest of ACPI.
This commit is contained in:
parent
3204b83aa5
commit
59e0238f99
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: acpi_acad.c,v 1.5 2002/10/02 16:33:36 thorpej Exp $ */
|
||||
/* $NetBSD: acpi_acad.c,v 1.6 2002/12/31 05:26:56 explorer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2001 Wasabi Systems, Inc.
|
||||
|
@ -40,7 +40,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: acpi_acad.c,v 1.5 2002/10/02 16:33:36 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: acpi_acad.c,v 1.6 2002/12/31 05:26:56 explorer Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -50,11 +50,27 @@ __KERNEL_RCSID(0, "$NetBSD: acpi_acad.c,v 1.5 2002/10/02 16:33:36 thorpej Exp $"
|
|||
#include <dev/acpi/acpireg.h>
|
||||
#include <dev/acpi/acpivar.h>
|
||||
|
||||
#include <dev/sysmon/sysmonvar.h>
|
||||
|
||||
#define ACPIACAD_NSENSORS 2
|
||||
|
||||
/* sensor indexes */
|
||||
#define ACPIACAD_CONNECTED 0
|
||||
#define ACPIACAD_DISCONNECTED 1
|
||||
|
||||
struct acpiacad_softc {
|
||||
struct device sc_dev; /* base device glue */
|
||||
struct acpi_devnode *sc_node; /* our ACPI devnode */
|
||||
int sc_flags; /* see below */
|
||||
int sc_status; /* power status */
|
||||
struct sysmon_envsys sc_sysmon;
|
||||
struct envsys_basic_info sc_info[ACPIACAD_NSENSORS];
|
||||
struct envsys_tre_data sc_data[ACPIACAD_NSENSORS];
|
||||
};
|
||||
|
||||
const struct envsys_range acpiacad_range[] = {
|
||||
{ 0, 2, ENVSYS_INDICATOR },
|
||||
{ 1, 0, -1},
|
||||
};
|
||||
|
||||
#define AACAD_F_VERBOSE 0x01 /* verbose events */
|
||||
|
@ -67,6 +83,9 @@ CFATTACH_DECL(acpiacad, sizeof(struct acpiacad_softc),
|
|||
|
||||
void acpiacad_get_status(void *);
|
||||
void acpiacad_notify_handler(ACPI_HANDLE, UINT32, void *context);
|
||||
static void acpiacad_init_envsys(struct acpiacad_softc *sc);
|
||||
static int acpiacad_gtredata(struct sysmon_envsys *, struct envsys_tre_data *);
|
||||
static int acpiacad_streinfo(struct sysmon_envsys *, struct envsys_basic_info *);
|
||||
|
||||
/*
|
||||
* acpiacad_match:
|
||||
|
@ -123,10 +142,7 @@ acpiacad_attach(struct device *parent, struct device *self, void *aux)
|
|||
/* Display the current state. */
|
||||
sc->sc_flags = AACAD_F_VERBOSE;
|
||||
acpiacad_get_status(sc);
|
||||
|
||||
/*
|
||||
* XXX Hook into sysmon here.
|
||||
*/
|
||||
acpiacad_init_envsys(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -143,6 +159,9 @@ acpiacad_get_status(void *arg)
|
|||
&sc->sc_status) != AE_OK)
|
||||
return;
|
||||
|
||||
sc->sc_data[ACPIACAD_CONNECTED].cur.data_s = !!(sc->sc_status);
|
||||
sc->sc_data[ACPIACAD_DISCONNECTED].cur.data_s = !(sc->sc_status);
|
||||
|
||||
if (sc->sc_flags & AACAD_F_VERBOSE)
|
||||
printf("%s: AC adapter %sconnected\n",
|
||||
sc->sc_dev.dv_xname, sc->sc_status == 0 ? "not " : "");
|
||||
|
@ -183,3 +202,63 @@ acpiacad_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context)
|
|||
sc->sc_dev.dv_xname, notify);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
acpiacad_init_envsys(struct acpiacad_softc *sc)
|
||||
{
|
||||
int i;
|
||||
|
||||
sc->sc_sysmon.sme_ranges = acpiacad_range;
|
||||
|
||||
for (i=0; i<ACPIACAD_NSENSORS; i++) {
|
||||
sc->sc_data[i].sensor = sc->sc_info[i].sensor = i;
|
||||
sc->sc_data[i].validflags |= (ENVSYS_FVALID | ENVSYS_FCURVALID);
|
||||
sc->sc_info[i].validflags = ENVSYS_FVALID;
|
||||
sc->sc_data[i].warnflags = 0;
|
||||
}
|
||||
|
||||
#define INITDATA(index, unit, string) \
|
||||
sc->sc_data[index].units = unit; \
|
||||
sc->sc_info[index].units = unit; \
|
||||
snprintf(sc->sc_info[index].desc, sizeof(sc->sc_info->desc), \
|
||||
"%s %s", sc->sc_dev.dv_xname, string); \
|
||||
|
||||
INITDATA(ACPIACAD_CONNECTED, ENVSYS_INDICATOR, "connected");
|
||||
INITDATA(ACPIACAD_DISCONNECTED, ENVSYS_INDICATOR, "disconnected");
|
||||
|
||||
sc->sc_sysmon.sme_sensor_info = sc->sc_info;
|
||||
sc->sc_sysmon.sme_sensor_data = sc->sc_data;
|
||||
sc->sc_sysmon.sme_cookie = sc;
|
||||
sc->sc_sysmon.sme_gtredata = acpiacad_gtredata;
|
||||
sc->sc_sysmon.sme_streinfo = acpiacad_streinfo;
|
||||
sc->sc_sysmon.sme_nsensors = ACPIACAD_NSENSORS;
|
||||
sc->sc_sysmon.sme_envsys_version = 1000;
|
||||
|
||||
if (sysmon_envsys_register(&sc->sc_sysmon))
|
||||
printf("%s: unable to register with sysmon\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
acpiacad_gtredata(struct sysmon_envsys *sme, struct envsys_tre_data *tred)
|
||||
{
|
||||
struct acpiacad_softc *sc = sme->sme_cookie;
|
||||
|
||||
/* XXX locking */
|
||||
*tred = sc->sc_data[tred->sensor];
|
||||
/* XXX locking */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
acpiacad_streinfo(struct sysmon_envsys *sme, struct envsys_basic_info *binfo)
|
||||
{
|
||||
|
||||
/* XXX Not implemented */
|
||||
binfo->validflags = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: acpi_bat.c,v 1.13 2002/12/30 13:06:43 explorer Exp $ */
|
||||
/* $NetBSD: acpi_bat.c,v 1.14 2002/12/31 05:26:56 explorer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2001 Bill Sommerfeld.
|
||||
|
@ -50,19 +50,46 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: acpi_bat.c,v 1.13 2002/12/30 13:06:43 explorer Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: acpi_bat.c,v 1.14 2002/12/31 05:26:56 explorer Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h> /* for hz */
|
||||
#include <sys/device.h>
|
||||
#include <sys/callout.h>
|
||||
#include <dev/sysmon/sysmonvar.h>
|
||||
|
||||
#include <dev/acpi/acpica.h>
|
||||
#include <dev/acpi/acpireg.h>
|
||||
#include <dev/acpi/acpivar.h>
|
||||
|
||||
#include <dev/sysmon/sysmonvar.h>
|
||||
/* sensor indexes */
|
||||
#define ACPIBAT_DCAPACITY 0
|
||||
#define ACPIBAT_LFCCAPACITY 1
|
||||
#define ACPIBAT_TECHNOLOGY 2
|
||||
#define ACPIBAT_DVOLTAGE 3
|
||||
#define ACPIBAT_WCAPACITY 4
|
||||
#define ACPIBAT_LCAPACITY 5
|
||||
#define ACPIBAT_VOLTAGE 6
|
||||
#define ACPIBAT_LOAD 7
|
||||
#define ACPIBAT_CAPACITY 8
|
||||
#define ACPIBAT_CHARGING 9
|
||||
#define ACPIBAT_DISCHARGING 10
|
||||
#define ACPIBAT_NSENSORS 11 /* number of sensors */
|
||||
|
||||
const struct envsys_range acpibat_range_amp[] = {
|
||||
{ 0, 1, ENVSYS_SVOLTS_DC },
|
||||
{ 1, 2, ENVSYS_SAMPS },
|
||||
{ 2, 3, ENVSYS_SAMPHOUR },
|
||||
{ 1, 0, -1 },
|
||||
};
|
||||
|
||||
const struct envsys_range acpibat_range_watt[] = {
|
||||
{ 0, 1, ENVSYS_SVOLTS_DC },
|
||||
{ 1, 2, ENVSYS_SWATTS },
|
||||
{ 2, 3, ENVSYS_SWATTHOUR },
|
||||
{ 1, 0, -1 },
|
||||
};
|
||||
|
||||
#define BAT_WORDS 13
|
||||
|
||||
|
@ -73,16 +100,11 @@ struct acpibat_softc {
|
|||
struct callout sc_callout; /* XXX temporary polling */
|
||||
int sc_present; /* is battery present? */
|
||||
int sc_status; /* power status */
|
||||
int sc_rate; /* current drain rate */
|
||||
int sc_capacity; /* current capacity */
|
||||
int sc_mv; /* current potential in mV */
|
||||
int sc_design_capacity; /* design capacity */
|
||||
int sc_pred_capacity; /* estimated current max */
|
||||
int sc_warn_capacity; /* warning level */
|
||||
int sc_low_capacity; /* low level */
|
||||
#if 0
|
||||
struct sysmon_power sc_sysmon; /* sysmon hook */
|
||||
#endif
|
||||
|
||||
struct sysmon_envsys sc_sysmon;
|
||||
struct envsys_basic_info sc_info[ACPIBAT_NSENSORS];
|
||||
struct envsys_tre_data sc_data[ACPIBAT_NSENSORS];
|
||||
|
||||
ACPI_OBJECT sc_Ret[BAT_WORDS]; /* Return Buffer */
|
||||
};
|
||||
|
||||
|
@ -96,14 +118,14 @@ struct acpibat_softc {
|
|||
* These flags are used to examine the battery charge/discharge/critical
|
||||
* state returned from a get-status command.
|
||||
*/
|
||||
#define ACPIBAT_DISCHARGING 0x00000001 /* battery is discharging */
|
||||
#define ACPIBAT_CHARGING 0x00000002 /* battery is charging */
|
||||
#define ACPIBAT_CRITICAL 0x00000004 /* battery is critical */
|
||||
#define ACPIBAT_ST_DISCHARGING 0x00000001 /* battery is discharging */
|
||||
#define ACPIBAT_ST_CHARGING 0x00000002 /* battery is charging */
|
||||
#define ACPIBAT_ST_CRITICAL 0x00000004 /* battery is critical */
|
||||
|
||||
/*
|
||||
* Flags for battery status from _STA return
|
||||
*/
|
||||
#define ACPIBAT_PRESENT 0x00000010 /* battery present */
|
||||
#define ACPIBAT_STA_PRESENT 0x00000010 /* battery present */
|
||||
|
||||
/*
|
||||
* These flags are used to set internal state in our softc.
|
||||
|
@ -123,8 +145,11 @@ CFATTACH_DECL(acpibat, sizeof(struct acpibat_softc),
|
|||
|
||||
static void acpibat_get_status(void *);
|
||||
static void acpibat_get_info(void *);
|
||||
static void acpibat_init_envsys(struct acpibat_softc *);
|
||||
void acpibat_notify_handler(ACPI_HANDLE, UINT32, void *context);
|
||||
static void acpibat_tick(void *);
|
||||
static int acpibat_gtredata(struct sysmon_envsys *, struct envsys_tre_data *);
|
||||
static int acpibat_streinfo(struct sysmon_envsys *, struct envsys_basic_info *);
|
||||
static int acpibat_battery_present(void *);
|
||||
|
||||
/*
|
||||
|
@ -192,15 +217,7 @@ acpibat_attach(struct device *parent, struct device *self, void *aux)
|
|||
sc->sc_flags = ABAT_F_VERBOSE;
|
||||
acpibat_get_info(sc);
|
||||
acpibat_get_status(sc);
|
||||
|
||||
/*
|
||||
* Hook into sysmon.
|
||||
*/
|
||||
#if 0
|
||||
if (sysmon_power_register(&sc->sc_sysmon))
|
||||
printf("%s: unable to to register with sysmon\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
#endif
|
||||
acpibat_init_envsys(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -249,7 +266,7 @@ acpibat_battery_present(void *arg)
|
|||
}
|
||||
sta = p1->Integer.Value;
|
||||
|
||||
sc->sc_present = (sta & ACPIBAT_PRESENT) ? 1 : 0;
|
||||
sc->sc_present = (sta & ACPIBAT_STA_PRESENT) ? 1 : 0;
|
||||
|
||||
return (sc->sc_present);
|
||||
}
|
||||
|
@ -297,22 +314,20 @@ acpibat_get_info(void *arg)
|
|||
if ((p2[0].Integer.Value & ACPIBAT_PWRUNIT_MA) != 0)
|
||||
sc->sc_flags |= ABAT_F_PWRUNIT_MA;
|
||||
|
||||
sc->sc_design_capacity = p2[1].Integer.Value;
|
||||
sc->sc_pred_capacity = p2[2].Integer.Value;
|
||||
sc->sc_warn_capacity = p2[6].Integer.Value;
|
||||
sc->sc_low_capacity = p2[7].Integer.Value;
|
||||
sc->sc_data[ACPIBAT_DCAPACITY].cur.data_s = p2[1].Integer.Value * 1000;
|
||||
sc->sc_data[ACPIBAT_LFCCAPACITY].cur.data_s = p2[2].Integer.Value * 1000;
|
||||
sc->sc_data[ACPIBAT_LFCCAPACITY].max.data_s = p2[1].Integer.Value * 1000;
|
||||
sc->sc_data[ACPIBAT_CAPACITY].max.data_s = p2[1].Integer.Value * 1000;
|
||||
sc->sc_data[ACPIBAT_TECHNOLOGY].cur.data_s = p2[3].Integer.Value;
|
||||
sc->sc_data[ACPIBAT_DVOLTAGE].cur.data_s = p2[4].Integer.Value * 1000;
|
||||
sc->sc_data[ACPIBAT_WCAPACITY].cur.data_s = p2[5].Integer.Value * 1000;
|
||||
sc->sc_data[ACPIBAT_LCAPACITY].cur.data_s = p2[6].Integer.Value * 1000;
|
||||
|
||||
printf("%s: %s %s %s %s\n",
|
||||
sc->sc_dev.dv_xname,
|
||||
p2[12].String.Pointer, p2[11].String.Pointer,
|
||||
p2[9].String.Pointer, p2[10].String.Pointer);
|
||||
|
||||
printf("%s: Design %d.%03d%s, Predicted %d.%03d%s Warn %d.%03d%s Low %d.%03d%s\n",
|
||||
sc->sc_dev.dv_xname,
|
||||
ACM_SCALE(sc->sc_design_capacity), ACM_CAPUNIT(sc),
|
||||
ACM_SCALE(sc->sc_pred_capacity), ACM_CAPUNIT(sc),
|
||||
ACM_SCALE(sc->sc_warn_capacity), ACM_CAPUNIT(sc),
|
||||
ACM_SCALE(sc->sc_low_capacity), ACM_CAPUNIT(sc));
|
||||
out:
|
||||
AcpiOsFree(buf.Pointer);
|
||||
}
|
||||
|
@ -325,13 +340,13 @@ out:
|
|||
static void
|
||||
acpibat_get_status(void *arg)
|
||||
{
|
||||
int flags;
|
||||
struct acpibat_softc *sc = arg;
|
||||
ACPI_OBJECT *p1, *p2;
|
||||
ACPI_STATUS rv;
|
||||
ACPI_BUFFER buf;
|
||||
|
||||
if (sc->sc_present != 1) {
|
||||
printf("%s: not present\n", sc->sc_dev.dv_xname);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -339,6 +354,7 @@ acpibat_get_status(void *arg)
|
|||
buf.Length = sizeof(sc->sc_Ret);
|
||||
|
||||
rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "_BST", NULL, &buf);
|
||||
|
||||
if (rv != AE_OK) {
|
||||
printf("bat: failed to evaluate _BST: %x\n", rv);
|
||||
return;
|
||||
|
@ -356,47 +372,18 @@ acpibat_get_status(void *arg)
|
|||
p2 = p1->Package.Elements;
|
||||
|
||||
sc->sc_status = p2[0].Integer.Value;
|
||||
sc->sc_rate = p2[1].Integer.Value;
|
||||
sc->sc_capacity = p2[2].Integer.Value;
|
||||
sc->sc_mv = p2[3].Integer.Value;
|
||||
sc->sc_data[ACPIBAT_LOAD].cur.data_s = p2[1].Integer.Value * 1000;
|
||||
sc->sc_data[ACPIBAT_CAPACITY].cur.data_s = p2[2].Integer.Value * 1000;
|
||||
sc->sc_data[ACPIBAT_VOLTAGE].cur.data_s = p2[3].Integer.Value * 1000;
|
||||
|
||||
if (sc->sc_flags & ABAT_F_VERBOSE) {
|
||||
|
||||
char *charge, *critical = "";
|
||||
|
||||
/*
|
||||
* Determine charging / discharging state.
|
||||
*/
|
||||
switch (sc->sc_status
|
||||
& (ACPIBAT_DISCHARGING | ACPIBAT_CHARGING)) {
|
||||
case ACPIBAT_DISCHARGING | ACPIBAT_CHARGING:
|
||||
charge = "confused";
|
||||
break;
|
||||
case ACPIBAT_DISCHARGING:
|
||||
charge = "discharging";
|
||||
break;
|
||||
case ACPIBAT_CHARGING:
|
||||
charge = "charging";
|
||||
break;
|
||||
default:
|
||||
charge = "idle";
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the critical bit is set, be loud about it.
|
||||
*/
|
||||
if ((sc->sc_status & ACPIBAT_CRITICAL) != 0)
|
||||
critical = " CRITICAL";
|
||||
|
||||
printf("%s: %s%s: %d.%03dV cap %d.%03d%s (%d%%) rate %d.%03d%s\n",
|
||||
sc->sc_dev.dv_xname, charge, critical,
|
||||
ACM_SCALE(sc->sc_mv),
|
||||
ACM_SCALE(sc->sc_capacity), ACM_CAPUNIT(sc),
|
||||
(sc->sc_design_capacity == 0) ? 0 :
|
||||
(sc->sc_capacity * 100) / sc->sc_design_capacity,
|
||||
ACM_SCALE(sc->sc_rate), ACM_RATEUNIT(sc));
|
||||
}
|
||||
flags = 0;
|
||||
if (sc->sc_data[ACPIBAT_CAPACITY].cur.data_s < sc->sc_data[ACPIBAT_WCAPACITY].cur.data_s)
|
||||
flags |= ENVSYS_WARN_UNDER;
|
||||
if (sc->sc_status & 4)
|
||||
flags |= ENVSYS_WARN_CRITUNDER;
|
||||
sc->sc_data[ACPIBAT_CAPACITY].warnflags = flags;
|
||||
sc->sc_data[ACPIBAT_DISCHARGING].cur.data_s = ((sc->sc_status & ACPIBAT_ST_DISCHARGING) != 0);
|
||||
sc->sc_data[ACPIBAT_CHARGING].cur.data_s = ((sc->sc_status & ACPIBAT_ST_CHARGING) != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -440,3 +427,93 @@ acpibat_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context)
|
|||
sc->sc_dev.dv_xname, notify);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
acpibat_init_envsys(struct acpibat_softc *sc)
|
||||
{
|
||||
int capunit, rateunit, i;
|
||||
const char *capstring, *ratestring;
|
||||
|
||||
if (sc->sc_flags & ABAT_F_PWRUNIT_MA) {
|
||||
sc->sc_sysmon.sme_ranges = acpibat_range_amp;
|
||||
capunit = ENVSYS_SAMPHOUR;
|
||||
capstring = "charge";
|
||||
rateunit = ENVSYS_SAMPS;
|
||||
ratestring = "current";
|
||||
} else {
|
||||
sc->sc_sysmon.sme_ranges = acpibat_range_watt;
|
||||
capunit = ENVSYS_SWATTHOUR;
|
||||
capstring = "energy";
|
||||
rateunit = ENVSYS_SWATTS;
|
||||
ratestring = "power";
|
||||
}
|
||||
|
||||
for (i = 0 ; i < ACPIBAT_NSENSORS; i++) {
|
||||
sc->sc_data[i].sensor = sc->sc_info[i].sensor = i;
|
||||
sc->sc_data[i].validflags |= (ENVSYS_FVALID | ENVSYS_FCURVALID);
|
||||
sc->sc_info[i].validflags = ENVSYS_FVALID;
|
||||
sc->sc_data[i].warnflags = 0;
|
||||
}
|
||||
#define INITDATA(index, unit, string) \
|
||||
sc->sc_data[index].units = unit; \
|
||||
sc->sc_info[index].units = unit; \
|
||||
snprintf(sc->sc_info[index].desc, sizeof(sc->sc_info->desc), \
|
||||
"%s %s", sc->sc_dev.dv_xname, string); \
|
||||
|
||||
INITDATA(ACPIBAT_DCAPACITY, capunit, "design cap");
|
||||
INITDATA(ACPIBAT_LFCCAPACITY, capunit, "lfc cap");
|
||||
INITDATA(ACPIBAT_TECHNOLOGY, ENVSYS_INTEGER, "technology");
|
||||
INITDATA(ACPIBAT_DVOLTAGE, ENVSYS_SVOLTS_DC, "design voltage");
|
||||
INITDATA(ACPIBAT_WCAPACITY, capunit, "warn cap");
|
||||
INITDATA(ACPIBAT_LCAPACITY, capunit, "low cap");
|
||||
INITDATA(ACPIBAT_VOLTAGE, ENVSYS_SVOLTS_DC, "voltage");
|
||||
INITDATA(ACPIBAT_LOAD, rateunit, ratestring);
|
||||
INITDATA(ACPIBAT_CAPACITY, capunit, capstring);
|
||||
INITDATA(ACPIBAT_CHARGING, ENVSYS_INDICATOR, "charging");
|
||||
INITDATA(ACPIBAT_DISCHARGING, ENVSYS_INDICATOR, "discharging");
|
||||
|
||||
/*
|
||||
* ACPIBAT_CAPACITY is the "gas gauge".
|
||||
* ACPIBAT_LFCCAPACITY is the "wear gauge".
|
||||
*/
|
||||
sc->sc_data[ACPIBAT_CAPACITY].validflags |=
|
||||
ENVSYS_FMAXVALID | ENVSYS_FFRACVALID;
|
||||
sc->sc_data[ACPIBAT_LFCCAPACITY].validflags |=
|
||||
ENVSYS_FMAXVALID | ENVSYS_FFRACVALID;
|
||||
|
||||
sc->sc_sysmon.sme_sensor_info = sc->sc_info;
|
||||
sc->sc_sysmon.sme_sensor_data = sc->sc_data;
|
||||
sc->sc_sysmon.sme_cookie = sc;
|
||||
sc->sc_sysmon.sme_gtredata = acpibat_gtredata;
|
||||
sc->sc_sysmon.sme_streinfo = acpibat_streinfo;
|
||||
sc->sc_sysmon.sme_nsensors = ACPIBAT_NSENSORS;
|
||||
sc->sc_sysmon.sme_envsys_version = 1000;
|
||||
|
||||
if (sysmon_envsys_register(&sc->sc_sysmon))
|
||||
printf("%s: unable to register with sysmon\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
}
|
||||
|
||||
int
|
||||
acpibat_gtredata(struct sysmon_envsys *sme, struct envsys_tre_data *tred)
|
||||
{
|
||||
struct acpibat_softc *sc = sme->sme_cookie;
|
||||
|
||||
/* XXX locking */
|
||||
acpibat_get_status(sc);
|
||||
*tred = sc->sc_data[tred->sensor];
|
||||
/* XXX locking */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
acpibat_streinfo(struct sysmon_envsys *sme, struct envsys_basic_info *binfo)
|
||||
{
|
||||
|
||||
/* XXX Not implemented */
|
||||
binfo->validflags = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.acpi,v 1.11 2002/12/28 19:31:35 jmcneill Exp $
|
||||
# $NetBSD: files.acpi,v 1.12 2002/12/31 05:26:57 explorer Exp $
|
||||
|
||||
include "dev/acpi/acpica/files.acpica"
|
||||
|
||||
|
@ -25,12 +25,12 @@ attach acpibut at acpi
|
|||
file dev/acpi/acpi_button.c acpibut
|
||||
|
||||
# ACPI AC Adapter
|
||||
device acpiacad
|
||||
device acpiacad: sysmon_envsys
|
||||
attach acpiacad at acpi
|
||||
file dev/acpi/acpi_acad.c acpiacad
|
||||
|
||||
# ACPI Control Method Battery
|
||||
device acpibat
|
||||
device acpibat: sysmon_envsys
|
||||
attach acpibat at acpi
|
||||
file dev/acpi/acpi_bat.c acpibat
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sysmon_envsys.c,v 1.3 2002/01/03 22:35:53 jdolecek Exp $ */
|
||||
/* $NetBSD: sysmon_envsys.c,v 1.4 2002/12/31 05:26:56 explorer Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 Zembu Labs, Inc.
|
||||
|
@ -41,7 +41,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys.c,v 1.3 2002/01/03 22:35:53 jdolecek Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys.c,v 1.4 2002/12/31 05:26:56 explorer Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
|
@ -136,21 +136,31 @@ sysmonioctl_envsys(dev_t dev, u_long cmd, caddr_t data, int flag,
|
|||
case ENVSYS_GRANGE:
|
||||
{
|
||||
struct envsys_range *rng = (void *) data;
|
||||
int i;
|
||||
|
||||
|
||||
/* Return empty range unless we find something better */
|
||||
rng->low = 1;
|
||||
rng->high = 0;
|
||||
|
||||
if (rng->units == -1) {
|
||||
rng->low = 0;
|
||||
rng->high = sysmon_envsys_next_sensor_index;
|
||||
break;
|
||||
}
|
||||
|
||||
sme = sysmon_envsys_find(0); /* XXX */
|
||||
if (sme == NULL) {
|
||||
/* Return empty range for `no sensors'. */
|
||||
rng->low = 1;
|
||||
rng->high = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rng->units < ENVSYS_NSENSORS)
|
||||
*rng = sme->sme_ranges[rng->units];
|
||||
else {
|
||||
/* Return empty range for unsupported sensor types. */
|
||||
rng->low = 1;
|
||||
rng->high = 0;
|
||||
for (i = 0;
|
||||
sme->sme_ranges[i].low <= sme->sme_ranges[i].high;
|
||||
i++) {
|
||||
if (sme->sme_ranges[i].units == rng->units) {
|
||||
*rng = sme->sme_ranges[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
sysmon_envsys_release(sme);
|
||||
break;
|
||||
|
@ -236,12 +246,6 @@ sysmon_envsys_register(struct sysmon_envsys *sme)
|
|||
|
||||
simple_lock(&sysmon_envsys_list_slock);
|
||||
|
||||
/* XXX Only get to register one, for now. */
|
||||
if (LIST_FIRST(&sysmon_envsys_list) != NULL) {
|
||||
error = EEXIST;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (sme->sme_envsys_version != SYSMON_ENVSYS_VERSION) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
|
|
Loading…
Reference in New Issue