Add ACPI AC adaptor and ACPI Control Method Battery.

And install notify handler for thermal zone .
This commit is contained in:
Takanori Watanabe 2000-12-22 14:41:55 +00:00
parent 67970143f8
commit d8c616aedc
7 changed files with 483 additions and 2 deletions

View File

@ -184,8 +184,10 @@ dev/aac/aac.c optional aac
dev/aac/aac_disk.c optional aac
dev/aac/aac_pci.c optional aac pci
dev/acpica/acpi.c optional acpica
dev/acpica/acpi_acad.c optional acpica
dev/acpica/acpi_apic.c optional acpica
dev/acpica/acpi_button.c optional acpica
dev/acpica/acpi_cmbat.c optional acpica
dev/acpica/acpi_ec.c optional acpica
dev/acpica/acpi_isa.c optional acpica isa
dev/acpica/acpi_lid.c optional acpica

138
sys/dev/acpica/acpi_acad.c Normal file
View File

@ -0,0 +1,138 @@
/*-
* Copyright (c) 2000 Takanori Watanabe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include "opt_acpi.h"
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <sys/ioccom.h>
#include <sys/malloc.h>
#include <sys/conf.h>
#include "acpi.h"
#include <dev/acpica/acpivar.h>
#include <dev/acpica/acpiio.h>
#define ACPI_DEVICE_CHECK_PNP 0x00
#define ACPI_DEVICE_CHECK_EXISTENCE 0x01
#define ACPI_POWERSOURCE_STAT_CHANGE 0x80
static void acpi_acad_get_status(void * );
static void acpi_acad_notify_handler(ACPI_HANDLE , UINT32 ,void *);
static int acpi_acad_probe(device_t);
static int acpi_acad_attach(device_t);
struct acpi_acad_softc {
int status;
};
static void
acpi_acad_get_status(void *context)
{
device_t dev = context;
struct acpi_acad_softc *sc = device_get_softc(dev);
ACPI_HANDLE h = acpi_get_handle(dev);
if (acpi_EvaluateNumber(h, "_PSR", &sc->status) != AE_OK)
return;
device_printf(dev,"%s\n",(sc->status) ? "On Line" : "Off Line");
}
static void
acpi_acad_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
{
device_t dev = context;
device_printf(dev, "Notify %d\n", notify);
switch (notify) {
case ACPI_DEVICE_CHECK_PNP:
case ACPI_DEVICE_CHECK_EXISTENCE:
case ACPI_POWERSOURCE_STAT_CHANGE:
/*Temporally. It is better to notify policy manager*/
AcpiOsQueueForExecution(OSD_PRIORITY_LO,
acpi_acad_get_status,context);
break;
default:
break;
}
}
static int
acpi_acad_probe(device_t dev)
{
if ((acpi_get_type(dev) == ACPI_TYPE_DEVICE) &&
acpi_MatchHid(dev, "ACPI0003")) {
/*
* Set device description
*/
device_set_desc(dev, "AC adapter");
return(0);
}
return(ENXIO);
}
static int
acpi_acad_attach(device_t dev)
{
ACPI_HANDLE handle = acpi_get_handle(dev);
AcpiInstallNotifyHandler(handle,
ACPI_DEVICE_NOTIFY,
acpi_acad_notify_handler, dev);
/*Installing system notify is not so good*/
AcpiInstallNotifyHandler(handle,
ACPI_SYSTEM_NOTIFY,
acpi_acad_notify_handler, dev);
acpi_acad_get_status((void *)dev);
return(0);
}
static device_method_t acpi_acad_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, acpi_acad_probe),
DEVMETHOD(device_attach, acpi_acad_attach),
{0, 0}
};
static driver_t acpi_acad_driver = {
"acpi_acad",
acpi_acad_methods,
sizeof(struct acpi_acad_softc),
};
static devclass_t acpi_acad_devclass;
DRIVER_MODULE(acpi_acad,acpi,acpi_acad_driver,acpi_acad_devclass,0,0);

275
sys/dev/acpica/acpi_cmbat.c Normal file
View File

@ -0,0 +1,275 @@
/*-
* Copyright (c) 2000 Takanori Watanabe
* Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include "opt_acpi.h"
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/ioccom.h>
#include <sys/conf.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <sys/malloc.h>
#include "acpi.h"
#include <dev/acpica/acpivar.h>
#include <dev/acpica/acpiio.h>
struct acpi_cmbat_softc {
device_t dev;
struct acpi_bif bif;
struct acpi_bst bst;
ACPI_BUFFER bif_buffer;
ACPI_BUFFER bst_buffer;
};
/* XXX: devclass_get_maxunit() don't give us the current allocated units... */
static int acpi_cmbat_units = 0;
#define ACPI_BATTERY_BST_CHANGE 0x80
#define ACPI_BATTERY_BIF_CHANGE 0x81
#define PKG_GETINT(res, tmp, idx, dest, label) do { \
tmp = &res->Package.Elements[idx]; \
if (tmp->Type != ACPI_TYPE_NUMBER) \
goto label ; \
dest = tmp->Number.Value; \
} while(0)
#define PKG_GETSTR(res, tmp, idx, dest, size, label) do { \
size_t length; \
length = size; \
tmp = &res->Package.Elements[idx]; \
bzero(dest, sizeof(dest)); \
switch (tmp->Type) { \
case ACPI_TYPE_STRING: \
if (tmp->String.Length < length) { \
length = tmp->String.Length; \
} \
strncpy(dest, tmp->String.Pointer, length); \
break; \
case ACPI_TYPE_BUFFER: \
if (tmp->Buffer.Length < length) { \
length = tmp->String.Length; \
} \
strncpy(dest, tmp->Buffer.Pointer, length); \
break; \
default: \
goto label; \
} \
dest[length-1] = '\0'; \
} while(0)
static void
acpi_cmbat_get_bst(void *context)
{
device_t dev = context;
struct acpi_cmbat_softc *sc = device_get_softc(dev);
ACPI_STATUS as;
ACPI_OBJECT *res, *tmp;
ACPI_HANDLE h = acpi_get_handle(dev);
retry:
if (sc->bst_buffer.Length == 0) {
sc->bst_buffer.Pointer = NULL;
as = AcpiEvaluateObject(h, "_BST", NULL, &sc->bst_buffer);
if (as != AE_BUFFER_OVERFLOW){
device_printf(dev, "CANNOT FOUND _BST (%d)\n", as);
return;
}
sc->bst_buffer.Pointer = malloc(sc->bst_buffer.Length, M_DEVBUF, M_NOWAIT);
if (sc->bst_buffer.Pointer == NULL) {
device_printf(dev,"malloc failed");
return;
}
}
as = AcpiEvaluateObject(h, "_BST", NULL, &sc->bst_buffer);
if (as == AE_BUFFER_OVERFLOW){
if (sc->bst_buffer.Pointer){
free(sc->bst_buffer.Pointer, M_DEVBUF);
}
device_printf(dev, "bst size changed to %d\n", sc->bst_buffer.Length);
sc->bst_buffer.Length = 0;
goto retry;
} else if (as != AE_OK){
device_printf(dev, "CANNOT FOUND _BST (%d)\n", as);
return;
}
res = sc->bst_buffer.Pointer;
if ((res->Type != ACPI_TYPE_PACKAGE) && (res->Package.Count < 4))
return ;
PKG_GETINT(res, tmp, 0, sc->bst.state, end);
PKG_GETINT(res, tmp, 1, sc->bst.rate, end);
PKG_GETINT(res, tmp, 2, sc->bst.cap, end);
PKG_GETINT(res, tmp, 3, sc->bst.volt, end);
end:
}
static void
acpi_cmbat_get_bif(void *context)
{
device_t dev = context;
struct acpi_cmbat_softc *sc = device_get_softc(dev);
ACPI_STATUS as;
ACPI_HANDLE h = acpi_get_handle(dev);
ACPI_OBJECT *res, *tmp;
retry:
if (sc->bif_buffer.Length == 0) {
sc->bif_buffer.Pointer = NULL;
as = AcpiEvaluateObject(h, "_BST", NULL, &sc->bif_buffer);
if (as != AE_BUFFER_OVERFLOW){
device_printf(dev, "CANNOT FOUND _BST (%d)\n", as);
return;
}
sc->bif_buffer.Pointer = malloc(sc->bif_buffer.Length, M_DEVBUF, M_NOWAIT);
if (sc->bif_buffer.Pointer == NULL) {
device_printf(dev,"malloc failed");
return;
}
}
as = AcpiEvaluateObject(h, "_BST", NULL, &sc->bif_buffer);
if (as == AE_BUFFER_OVERFLOW){
if (sc->bif_buffer.Pointer){
free(sc->bif_buffer.Pointer, M_DEVBUF);
}
device_printf(dev, "bif size changed to %d\n", sc->bif_buffer.Length);
sc->bif_buffer.Length = 0;
goto retry;
} else if (as != AE_OK){
device_printf(dev, "CANNOT FOUND _BST (%d)\n", as);
return;
}
res = sc->bif_buffer.Pointer;
if ((res->Type != ACPI_TYPE_PACKAGE) && (res->Package.Count < 13))
return ;
PKG_GETINT(res, tmp, 0, sc->bif.unit, end);
PKG_GETINT(res, tmp, 1, sc->bif.dcap, end);
PKG_GETINT(res, tmp, 2, sc->bif.lfcap, end);
PKG_GETINT(res, tmp, 3, sc->bif.btech, end);
PKG_GETINT(res, tmp, 4, sc->bif.dvol, end);
PKG_GETINT(res, tmp, 5, sc->bif.wcap, end);
PKG_GETINT(res, tmp, 6, sc->bif.lcap, end);
PKG_GETINT(res, tmp, 7, sc->bif.gra1, end);
PKG_GETINT(res, tmp, 8, sc->bif.gra2, end);
PKG_GETSTR(res, tmp, 9, sc->bif.model, ACPI_CMBAT_MAXSTRLEN, end);
PKG_GETSTR(res, tmp, 10, sc->bif.serial, ACPI_CMBAT_MAXSTRLEN, end);
PKG_GETSTR(res, tmp, 11, sc->bif.type, ACPI_CMBAT_MAXSTRLEN, end);
PKG_GETSTR(res, tmp, 12, sc->bif.oeminfo, ACPI_CMBAT_MAXSTRLEN, end);
end:
}
static void
acpi_cmbat_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
{
switch (notify) {
#if 0
/* XXX
* AML method execution is somewhat heavy even using swi.
* better to disable them until we fix the problem.
*/
case ACPI_BATTERY_BST_CHANGE:
AcpiOsQueueForExecution(OSD_PRIORITY_LO,
acpi_cmbat_get_bst, context);
break;
case ACPI_BATTERY_BIF_CHANGE:
AcpiOsQueueForExecution(OSD_PRIORITY_LO,
acpi_cmbat_get_bif, context);
break;
#endif
default:
break;
}
}
static int
acpi_cmbat_probe(device_t dev)
{
if ((acpi_get_type(dev) == ACPI_TYPE_DEVICE) &&
acpi_MatchHid(dev, "PNP0C0A")) {
/*
* Set device description
*/
device_set_desc(dev, "Control method Battery");
return(0);
}
return(ENXIO);
}
static int
acpi_cmbat_attach(device_t dev)
{
ACPI_HANDLE handle = acpi_get_handle(dev);
struct acpi_cmbat_softc *sc;
sc = device_get_softc(dev);
AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY,
acpi_cmbat_notify_handler,dev);
bzero(&sc->bif_buffer, sizeof(sc->bif_buffer));
bzero(&sc->bst_buffer, sizeof(sc->bst_buffer));
acpi_cmbat_get_bif(dev);
acpi_cmbat_get_bst(dev);
acpi_cmbat_units++;
return(0);
}
static device_method_t acpi_cmbat_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, acpi_cmbat_probe),
DEVMETHOD(device_attach, acpi_cmbat_attach),
{0, 0}
};
static driver_t acpi_cmbat_driver = {
"acpi_cmbat",
acpi_cmbat_methods,
sizeof(struct acpi_cmbat_softc),
};
static devclass_t acpi_cmbat_devclass;
DRIVER_MODULE(acpi_cmbat, acpi, acpi_cmbat_driver, acpi_cmbat_devclass, 0, 0);

View File

@ -51,7 +51,7 @@ struct acpi_tz_softc {
static int acpi_tz_probe(device_t dev);
static int acpi_tz_attach(device_t dev);
static void acpi_tz_check_tripping_point(void *context);
static device_method_t acpi_tz_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, acpi_tz_probe),
@ -82,7 +82,38 @@ acpi_tz_probe(device_t dev)
}
return_VALUE(ENXIO);
}
static void acpi_tz_check_tripping_point(void *context)
{
device_t dev = context;
struct acpi_tz_softc *sc;
UINT32 param[4];
ACPI_BUFFER b;
sc = device_get_softc(dev);
b.Pointer = &param[0];
b.Length = sizeof(param);
if((AcpiEvaluateObject(sc->tz_handle,"_TMP",NULL,&b)) != AE_OK){
device_printf(dev,"CANNOT FOUND _TMP\n");
return;
}
device_printf(dev,"%d.%d K\n",param[1]/10,param[1]%10);
return;
}
#define ACPI_TZ_STATUS_CHANGE 0x80
#define ACPI_TZ_TRIPPOINT_CHANGE 0x81
static void acpi_tz_notify_handler( ACPI_HANDLE h,UINT32 notify, void *context)
{
device_t dev = context;
switch(notify){
case ACPI_TZ_STATUS_CHANGE:
case ACPI_TZ_TRIPPOINT_CHANGE:
/*Check trip point*/
AcpiOsQueueForExecution(OSD_PRIORITY_LO,
acpi_tz_check_tripping_point,context);
break;
}
}
static int
acpi_tz_attach(device_t dev)
{
@ -109,6 +140,15 @@ acpi_tz_attach(device_t dev)
return_VALUE(ENXIO);
}
device_printf(sc->tz_dev, "current temperature %d.%dC\n", TZ_KELVTOC(param[1]));
AcpiInstallNotifyHandler(sc->tz_handle,ACPI_DEVICE_NOTIFY,
acpi_tz_notify_handler,dev);
return_VALUE(0);
}

View File

@ -34,6 +34,30 @@
#define ACPIIO_DISABLE _IO('P', 2)
#define ACPIIO_SETSLPSTATE _IOW('P', 3, int)
#define ACPI_CMBAT_MAXSTRLEN 32
struct acpi_bif {
u_int32_t unit; /* 0 for mWh, 1 for mAh */
u_int32_t dcap; /* Design Capacity */
u_int32_t btech; /* Battery Technorogy */
u_int32_t lfcap; /* Last Full capacity */
u_int32_t dvol; /* Design voltage (mV) */
u_int32_t wcap; /* WARN capacity */
u_int32_t lcap; /* Low capacity */
u_int32_t gra1; /* Granulity 1(Warn to Low) */
u_int32_t gra2; /* Granulity 2(Full to Warn) */
char model[ACPI_CMBAT_MAXSTRLEN]; /* model identifier */
char serial[ACPI_CMBAT_MAXSTRLEN]; /* Serial number */
char type[ACPI_CMBAT_MAXSTRLEN]; /* Type */
char oeminfo[ACPI_CMBAT_MAXSTRLEN]; /* OEM infomation */
};
struct acpi_bst {
u_int32_t state; /* Battery State */
u_int32_t rate; /* Present Rate */
u_int32_t cap; /* Remaining Capacity */
u_int32_t volt; /* Present Voltage */
};
#ifdef _KERNEL
extern int acpi_register_ioctl(u_long cmd, int (* fn)(u_long cmd, caddr_t addr, void *arg), void *arg);
extern void acpi_deregister_ioctl(u_long cmd, int (* fn)(u_long cmd, caddr_t addr, void *arg));

View File

@ -33,6 +33,7 @@ SRCS += rscreate.c rsdump.c rsio.c rsirq.c rslist.c rsmemory.c
SRCS += rsmisc.c rsutils.c rsxface.c tbconvrt.c tbget.c tbinstal.c tbutils.c
SRCS += tbxface.c tbxfroot.c acpi.c acpi_apic.c acpi_button.c
SRCS += acpi_ec.c acpi_isa.c acpi_lid.c acpi_pcib.c acpi_processor.c
SRCS += acpi_acad.c acpi_cmbat.c
SRCS += acpi_resource.c acpi_thermal.c acpi_timer.c OsdDebug.c
SRCS += OsdHardware.c OsdInterrupt.c OsdMemory.c OsdSchedule.c
SRCS += OsdStream.c OsdSynch.c OsdEnvironment.c

View File

@ -33,6 +33,7 @@ SRCS += rscreate.c rsdump.c rsio.c rsirq.c rslist.c rsmemory.c
SRCS += rsmisc.c rsutils.c rsxface.c tbconvrt.c tbget.c tbinstal.c tbutils.c
SRCS += tbxface.c tbxfroot.c acpi.c acpi_apic.c acpi_button.c
SRCS += acpi_ec.c acpi_isa.c acpi_lid.c acpi_pcib.c acpi_processor.c
SRCS += acpi_acad.c acpi_cmbat.c
SRCS += acpi_resource.c acpi_thermal.c acpi_timer.c OsdDebug.c
SRCS += OsdHardware.c OsdInterrupt.c OsdMemory.c OsdSchedule.c
SRCS += OsdStream.c OsdSynch.c OsdEnvironment.c