summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/etc.sparc/MAKEDEV.md3
-rw-r--r--share/man/man4/man4.sparc/tctrl.4224
-rw-r--r--sys/arch/sparc/dev/tctrl.c340
-rw-r--r--sys/arch/sparc/dev/ts102reg.h3
-rw-r--r--sys/arch/sparc/include/apmvar.h124
-rw-r--r--sys/arch/sparc/include/conf.h10
-rw-r--r--sys/arch/sparc/sparc/conf.c6
-rw-r--r--usr.sbin/apm/Makefile6
-rw-r--r--usr.sbin/apmd/Makefile6
9 files changed, 701 insertions, 21 deletions
diff --git a/etc/etc.sparc/MAKEDEV.md b/etc/etc.sparc/MAKEDEV.md
index d29b4dfd6b4..0bf0385bd45 100644
--- a/etc/etc.sparc/MAKEDEV.md
+++ b/etc/etc.sparc/MAKEDEV.md
@@ -1,5 +1,5 @@
vers(__file__,
- {-$OpenBSD: MAKEDEV.md,v 1.25 2005/03/01 18:22:32 miod Exp $-},
+ {-$OpenBSD: MAKEDEV.md,v 1.26 2005/03/29 16:26:40 miod Exp $-},
etc.MACHINE)dnl
dnl
dnl Copyright (c) 2001-2004 Todd T. Fries <todd@OpenBSD.org>
@@ -89,6 +89,7 @@ _DEV(wsmux, 81)
_TITLE(point)
_DEV(wsmouse, 80)
_TITLE(spec)
+_DEV(apm, 30)
_DEV(au, 69)
_DEV(bpf, 105)
_DEV(fdesc, 24)
diff --git a/share/man/man4/man4.sparc/tctrl.4 b/share/man/man4/man4.sparc/tctrl.4
index 7cf62ab154a..d1240106b35 100644
--- a/share/man/man4/man4.sparc/tctrl.4
+++ b/share/man/man4/man4.sparc/tctrl.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tctrl.4,v 1.6 2003/06/23 09:34:53 miod Exp $
+.\" $OpenBSD: tctrl.4,v 1.7 2005/03/29 16:26:43 miod Exp $
.\"
.\" Copyright (c) 1999 Jason L. Wright (jason@thought.net)
.\" All rights reserved.
@@ -24,7 +24,17 @@
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd June 22, 2003
+.\" APM description:
+.\"
+.\" Copyright (c) 1998 Marco S. Hyman
+.\"
+.\" Permission to copy all or part of this material for any purpose is
+.\" granted provided that the above copyright notice and this paragraph
+.\" are duplicated in all copies. THIS SOFTWARE IS PROVIDED ``AS IS''
+.\" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+.\" LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+.\" FOR A PARTICULAR PURPOSE.
+.Dd March 29, 2005
.Dt TCTRL 4 sparc
.Os
.Sh NAME
@@ -38,6 +48,7 @@ The
driver provides control over many functions on the
.Tn Tadpole SPARCbook
3 series laptops, via their TS102 chip.
+.Pp
The microcontroller is used to power the TFT display down when the
laptop lid is closed and when the screen is blanked by the
.Xr pninek 4
@@ -51,12 +62,219 @@ is also used to power the laptop off when the
system call is used with the
.Ar RB_POWERDOWN
flag is set.
+.Pp
The PCMCIA part of the controller is managed by the
.Xr tslot 4
driver.
+.Sh POWER MANAGEMENT INTERFACE
+The
+.Nm
+driver provides an interface which simulates the Advanced Power Management
+.Pq Tn APM
+BIOS functions encountered on some x86 hardware.
+The BIOS functions are translated into the appropriate microcontroller requests.
+Currently only battery level, AC connection, and charging status are available
+from the
+.Nm
+device.
+Suspend/resume and other power events are not yet supported.
+.Pp
+The
+.Nm
+driver implements the following
+.Xr ioctl 2
+calls.
+They are defined in
+.Aq Pa machine/apmvar.h .
+.Bl -tag -width Ds
+.\" .It Dv APM_IOC_STANDBY
+.\" .Em NOT YET SUPPORTED on sparc
+.\" .Pq Li "no parameters"
+.\" Request
+.\" .Dq standby
+.\" mode.
+.\" .It Dv APM_IOC_SUSPEND
+.\" .Em NOT YET SUPPORTED on sparc
+.\" .Pq Li "no parameters"
+.\" Request
+.\" .Dq suspend
+.\" mode.
+.It Dv APM_IOC_GETPOWER
+.Pq Li "struct apm_power_info"
+Request the current power state.
+The argument structure is as follows:
+.Bd -literal -offset indent
+struct apm_power_info {
+ u_char battery_state;
+ u_char ac_state;
+ u_char battery_life;
+ u_char spare1;
+ u_int minutes_left;
+ u_int spare2[6];
+};
+.Ed
+.Pp
+The following values are defined for
+.Va battery_state :
+.Bl -tag -width Ds
+.It Dv APM_BATT_HIGH
+Battery has a high state of charge.
+.It Dv APM_BATT_LOW
+Battery has a low state of charge.
+.It Dv APM_BATT_CRITICAL
+Battery has a critical state of charge.
+.It Dv APM_BATT_CHARGING
+Battery is not high, low, or critical and is currently charging.
+.It Dv APM_BATT_UNKNOWN
+Can not read the current battery state.
+.\" .It Dv APM_BATTERY_ABSENT
+.\" No battery installed.
+.El
+.Pp
+The following values are defined for
+.Va ac_state :
+.Bl -tag -width Ds
+.It Dv APM_AC_OFF
+External power not detected.
+.It Dv APM_AC_ON
+External power detected.
+.\" .It Dv APM_AC_BACKUP
+.\" Backup power in use.
+.\" .It Dv APM_AC_UNKNOWN
+.\" External power state unknown.
+.El
+.Pp
+The
+.Va battery_life
+value contains the estimated percentage of battery life available.
+100% indicates a full charge.
+.Pp
+The
+.Va minutes_left
+value is always -1,
+as the hardware does not provide an estimated number of minutes of
+battery life remaining.
+.\" .It Dv APM_IOC_NEXTEVENT
+.\" .Em NOT YET SUPPORTED on sparc
+.\" .Pq Li "struct apm_event_info"
+.\" The
+.\" .Tn APM
+.\" driver stores up to
+.\" .Dv APM_NEVENTS
+.\" events.
+.\" This was defined as 16 at the time this documentation was written.
+.\" If the event list is full when a new event is detected the new event is lost.
+.\" .Dv APM_IOC_NEXTEVENT
+.\" ioctl returns the next event on the list or
+.\" .Er EAGAIN
+.\" if the event list is empty.
+.\" The format of the returned event is:
+.\" .Bd -literal -offset indent
+.\" struct apm_event_info {
+.\" u_int type;
+.\" u_int index;
+.\" u_int spare[8];
+.\" };
+.\" .Ed
+.\" where
+.\" .Va index
+.\" is a sequential count of events that can be used to check if any
+.\" events were lost and
+.\" .Va type
+.\" is one of:
+.\" .Pp
+.\" .Bl -tag -width Ds -offset indent -compact
+.\" .It Dv APM_STANDBY_REQ
+.\" .It Dv APM_SUSPEND_REQ
+.\" .It Dv APM_NORMAL_RESUME
+.\" .It Dv APM_CRIT_RESUME
+.\" .It Dv APM_BATTERY_LOW
+.\" .It Dv APM_POWER_CHANGE
+.\" .It Dv APM_UPDATE_TIME
+.\" .It Dv APM_CRIT_SUSPEND_REQ
+.\" .It Dv APM_USER_STANDBY_REQ
+.\" .It Dv APM_USER_SUSPEND_REQ
+.\" .It Dv APM_SYS_STANDBY_RESUME
+.\" .El
+.\" .It Dv APM_IOC_DEV_CTL
+.\" .Em NOT YET SUPPORTED on sparc
+.\" .Pq Li "struct apm_ctl"
+.\" Allows an application to directly set the
+.\" .Tm APM
+.\" operating mode.
+.\" The argument structure is as follows:
+.\" .Bd -literal -offset indent
+.\" struct apm_ctl {
+.\" u_int dev;
+.\" u_int mode;
+.\" };
+.\" .Ed
+.\" .Pp
+.\" .Va dev
+.\" indicates the device, typically
+.\" .Dv APM_DEV_ALLDEVS .
+.\" .Pp
+.\" .Va mode
+.\" indicates the desired operating mode.
+.\" Possible values are
+.\" .Bl -tag -compact -offset indent
+.\" .It Dv APM_SYS_READY
+.\" .It Dv APM_SYS_STANDBY
+.\" .It Dv APM_SYS_SUSPEND
+.\" .It Dv APM_SYS_OFF
+.\" .It Dv APM_LASTREQ_INPROG
+.\" .It Dv APM_LASTREQ_REJECTED
+.\" .El
+.It Dv APM_IOC_PRN_CTL
+.Pq Li "int"
+This
+.Xr ioctl 2
+controls message output by the
+.Nm
+driver when a power change event is detected.
+The integer parameter is one of:
+.Bl -tag -width Ds
+.It Dv APM_PRINT_ON
+All power change events result in a message.
+This is the normal operating mode for the driver.
+.It Dv APM_PRINT_OFF
+Power change event messages are suppressed.
+.It Dv APM_PRINT_PCT
+Power change event messages are suppressed unless the estimated
+battery life percentage changes.
+.El
+.\" .Pp
+.\" However, in no case will power status messages be displayed until the
+.\" battery life goes below the percentage in the
+.\" .Xr sysctl 8
+.\" state variable
+.\" .Dv machdep.apmwarn .
+.\" Setting
+.\" .Dv machdep.apmwarn
+.\" to zero disables all warnings regardless of the
+.\" .Dv APM_IOC_PRN_CTL
+.\" setting.
+.El
+.Sh FILES
+.Bl -tag -width /dev/apmctl
+.It Pa /dev/apm
+APM data device.
+May only be opened read-only.
+May be opened by multiple concurrent users.
+.It Pa /dev/apmctl
+APM control device.
+May be opened read-write or write-only.
+May only be opened by one user at a time.
+An attempt to open the file when in use will fail, returning
+.Er EBUSY .
+.El
.Sh SEE ALSO
.Xr reboot 2 ,
.Xr intro 4 ,
.Xr pninek 4 ,
.Xr pnozz 4 ,
-.Xr tslot 4
+.Xr tslot 4 ,
+.Xr apm 8 ,
+.Xr apmd 8
+.Sh BUGS
+Not all power management functions of the microcontroller are supported.
diff --git a/sys/arch/sparc/dev/tctrl.c b/sys/arch/sparc/dev/tctrl.c
index 6409aaca8c7..3f76cf2660c 100644
--- a/sys/arch/sparc/dev/tctrl.c
+++ b/sys/arch/sparc/dev/tctrl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tctrl.c,v 1.9 2005/03/29 12:55:55 miod Exp $ */
+/* $OpenBSD: tctrl.c,v 1.10 2005/03/29 16:26:44 miod Exp $ */
/* $NetBSD: tctrl.c,v 1.2 1999/08/11 00:46:06 matt Exp $ */
/*-
@@ -36,20 +36,75 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * The /dev/apm{,ctl} interface code falls under the following license
+ * terms:
+ *
+ * Copyright (c) 1998-2001 Michael Shalayeff. All rights reserved.
+ * Copyright (c) 1995 John T. Kohl. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 MIND, 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.
+ */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/device.h>
+#include <sys/event.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/proc.h>
#include <sys/timeout.h>
+#include <machine/apmvar.h>
#include <machine/autoconf.h>
+#include <machine/conf.h>
#include <machine/cpu.h>
#include <sparc/dev/ts102reg.h>
#include <sparc/dev/tctrlvar.h>
+/*
+ * Flags to control kernel display
+ * SCFLAG_NOPRINT: do not output APM power messages due to
+ * a power change event.
+ *
+ * SCFLAG_PCTPRINT: do not output APM power messages due to
+ * to a power change event unless the battery
+ * percentage changes.
+ */
+
+#define SCFLAG_NOPRINT 0x0008000
+#define SCFLAG_PCTPRINT 0x0004000
+#define SCFLAG_PRINT (SCFLAG_NOPRINT|SCFLAG_PCTPRINT)
+
const char *tctrl_ext_statuses[16] = {
"main power available",
"internal battery attached",
@@ -96,6 +151,10 @@ struct tctrl_softc {
u_int sc_bellvol;
struct timeout sc_tmo;
+
+ /* /dev/apm{,ctl} fields */
+ struct klist sc_note;
+ u_int sc_apmflags;
};
int tctrl_match(struct device *, void *, void *);
@@ -113,6 +172,8 @@ void tctrl_request(struct tctrl_softc *, struct tctrl_req *);
void tctrl_tft(struct tctrl_softc *);
void tctrl_write_data(struct tctrl_softc *, u_int8_t);
+int apm_record_event(struct tctrl_softc *, u_int);
+
struct cfattach tctrl_ca = {
sizeof(struct tctrl_softc), tctrl_match, tctrl_attach
};
@@ -425,17 +486,23 @@ tctrl_read_event_status(void *arg)
#ifdef TCTRLDEBUG
/* Obviously status change */
if (v & TS102_EVENT_STATUS_VERY_LOW_POWER_WARNING) {
- printf("%s: Battery level change\n", sc->sc_dev.dv_xname);
+ if (sc->sc_apmflags & SCFLAG_PCTPRINT)
+ printf("%s: Battery level change\n",
+ sc->sc_dev.dv_xname);
}
#endif
if (v & TS102_EVENT_STATUS_LOW_POWER_WARNING) {
- printf("%s: LOW POWER WARNING!\n", sc->sc_dev.dv_xname);
+ if ((sc->sc_apmflags & SCFLAG_NOPRINT) == 0)
+ printf("%s: LOW POWER WARNING!\n", sc->sc_dev.dv_xname);
+ apm_record_event(sc, APM_BATTERY_LOW);
}
if (v & TS102_EVENT_STATUS_DC_STATUS_CHANGE) {
tctrl_read_ext_status(sc);
- printf("%s: main power %s\n", sc->sc_dev.dv_xname,
- (sc->sc_ext_status & TS102_EXT_STATUS_MAIN_POWER_AVAILABLE) ?
- "restored" : "removed");
+ if ((sc->sc_apmflags & SCFLAG_NOPRINT) == 0)
+ printf("%s: main power %s\n", sc->sc_dev.dv_xname,
+ (sc->sc_ext_status & TS102_EXT_STATUS_MAIN_POWER_AVAILABLE) ?
+ "restored" : "removed");
+ apm_record_event(sc, APM_POWER_CHANGE);
#if 0 /* automatically done for us */
tctrl_lcd(sc, ~TS102_LCD_DC_OK,
sc->sc_ext_status & TS102_EXT_STATUS_MAIN_POWER_AVAILABLE ?
@@ -788,3 +855,264 @@ tadpole_bell(u_int duration, u_int freq, u_int volume)
return (1);
}
+
+/*
+ * /dev/apm{,ctl} interface code
+ */
+
+#define APMUNIT(dev) (minor(dev)&0xf0)
+#define APMDEV(dev) (minor(dev)&0x0f)
+#define APMDEV_NORMAL 0
+#define APMDEV_CTL 8
+
+int apmkqfilter(dev_t dev, struct knote *kn);
+void filt_apmrdetach(struct knote *kn);
+int filt_apmread(struct knote *kn, long hint);
+
+struct filterops apmread_filtops =
+ { 1, NULL, filt_apmrdetach, filt_apmread};
+
+#define SCFLAG_OREAD (1 << 0)
+#define SCFLAG_OWRITE (1 << 1)
+#define SCFLAG_OPEN (SCFLAG_OREAD|SCFLAG_OWRITE)
+
+int
+apmopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ struct tctrl_softc *sc;
+ int error = 0;
+
+ if (tctrl_cd.cd_devs == NULL
+ || tctrl_cd.cd_ndevs == 0
+ || tctrl_cd.cd_devs[0] == NULL) {
+ return (ENXIO);
+ }
+
+ /* apm0 only */
+ if (APMUNIT(dev) != 0)
+ return (ENODEV);
+
+ sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0];
+
+ switch (APMDEV(dev)) {
+ case APMDEV_CTL:
+ if (!(flag & FWRITE)) {
+ error = EINVAL;
+ break;
+ }
+ if (sc->sc_apmflags & SCFLAG_OWRITE) {
+ error = EBUSY;
+ break;
+ }
+ sc->sc_apmflags |= SCFLAG_OWRITE;
+ break;
+ case APMDEV_NORMAL:
+ if (!(flag & FREAD) || (flag & FWRITE)) {
+ error = EINVAL;
+ break;
+ }
+ sc->sc_apmflags |= SCFLAG_OREAD;
+ break;
+ default:
+ error = ENXIO;
+ break;
+ }
+ return (error);
+}
+
+int
+apmclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ struct tctrl_softc *sc;
+
+ if (tctrl_cd.cd_devs == NULL
+ || tctrl_cd.cd_ndevs == 0
+ || tctrl_cd.cd_devs[0] == NULL) {
+ return (ENXIO);
+ }
+
+ /* apm0 only */
+ if (APMUNIT(dev) != 0)
+ return (ENODEV);
+
+ sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0];
+
+ switch (APMDEV(dev)) {
+ case APMDEV_CTL:
+ sc->sc_apmflags &= ~SCFLAG_OWRITE;
+ break;
+ case APMDEV_NORMAL:
+ sc->sc_apmflags &= ~SCFLAG_OREAD;
+ break;
+ }
+ return (0);
+}
+
+int
+apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct tctrl_softc *sc;
+ struct tctrl_req req;
+ struct apm_power_info *power;
+ u_int8_t c;
+ int error = 0;
+
+ if (tctrl_cd.cd_devs == NULL
+ || tctrl_cd.cd_ndevs == 0
+ || tctrl_cd.cd_devs[0] == NULL) {
+ return (ENXIO);
+ }
+
+ /* apm0 only */
+ if (APMUNIT(dev) != 0)
+ return (ENODEV);
+
+ sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0];
+
+ switch (cmd) {
+ /* some ioctl names from linux */
+ case APM_IOC_STANDBY:
+ if ((flag & FWRITE) == 0)
+ error = EBADF;
+ else
+ error = EOPNOTSUPP; /* XXX */
+ break;
+ case APM_IOC_SUSPEND:
+ if ((flag & FWRITE) == 0)
+ error = EBADF;
+ else
+ error = EOPNOTSUPP; /* XXX */
+ break;
+ case APM_IOC_PRN_CTL:
+ if ((flag & FWRITE) == 0)
+ error = EBADF;
+ else {
+ int flag = *(int *)data;
+ switch (flag) {
+ case APM_PRINT_ON: /* enable printing */
+ sc->sc_apmflags &= ~SCFLAG_PRINT;
+ break;
+ case APM_PRINT_OFF: /* disable printing */
+ sc->sc_apmflags &= ~SCFLAG_PRINT;
+ sc->sc_apmflags |= SCFLAG_NOPRINT;
+ break;
+ case APM_PRINT_PCT: /* disable some printing */
+ sc->sc_apmflags &= ~SCFLAG_PRINT;
+ sc->sc_apmflags |= SCFLAG_PCTPRINT;
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ }
+ break;
+ case APM_IOC_GETPOWER:
+ power = (struct apm_power_info *)data;
+
+ req.cmdbuf[0] = TS102_OP_RD_INT_CHARGE_RATE;
+ req.cmdlen = 1;
+ req.rsplen = 2;
+ tctrl_request(sc, &req);
+ if (req.rspbuf[0] != 0)
+ power->battery_state = APM_BATT_CHARGING;
+ else
+ power->battery_state = APM_BATT_UNKNOWN;
+
+ req.cmdbuf[0] = TS102_OP_RD_INT_CHARGE_LEVEL;
+ req.cmdlen = 1;
+ req.rsplen = 3;
+ tctrl_request(sc, &req);
+
+ c = req.rspbuf[0];
+ if (c == TS102_CHARGE_UNKNOWN)
+ c = 0;
+ power->battery_life = c;
+ power->minutes_left = (u_int)-1; /* unknown */
+ if (power->battery_state != APM_BATT_CHARGING) {
+ if (c < 0x20)
+ power->battery_state = APM_BATT_CRITICAL;
+ else if (c < 0x40)
+ power->battery_state = APM_BATT_HIGH;
+ else if (c < 0x66)
+ power->battery_state = APM_BATT_HIGH;
+ }
+
+#if 0
+ tctrl_read_ext_status(sc);
+#endif
+ if (sc->sc_ext_status & TS102_EXT_STATUS_MAIN_POWER_AVAILABLE)
+ power->ac_state = APM_AC_ON;
+ else
+ power->ac_state = APM_AC_OFF;
+ break;
+
+ default:
+ error = ENOTTY;
+ }
+
+ return (error);
+}
+
+int
+apm_record_event(struct tctrl_softc *sc, u_int type)
+{
+ static int apm_evindex;
+
+ /* skip if no user waiting */
+ if ((sc->sc_apmflags & SCFLAG_OPEN) == 0)
+ return (1);
+
+ apm_evindex++;
+ KNOTE(&sc->sc_note, APM_EVENT_COMPOSE(type, apm_evindex));
+
+ return (0);
+}
+
+void
+filt_apmrdetach(struct knote *kn)
+{
+ struct tctrl_softc *sc = (struct tctrl_softc *)kn->kn_hook;
+
+ SLIST_REMOVE(&sc->sc_note, kn, knote, kn_selnext);
+}
+
+int
+filt_apmread(struct knote *kn, long hint)
+{
+ /* XXX weird kqueue_scan() semantics */
+ if (hint && !kn->kn_data)
+ kn->kn_data = (int)hint;
+
+ return (1);
+}
+
+int
+apmkqfilter(dev_t dev, struct knote *kn)
+{
+ struct tctrl_softc *sc;
+
+ if (tctrl_cd.cd_devs == NULL
+ || tctrl_cd.cd_ndevs == 0
+ || tctrl_cd.cd_devs[0] == NULL) {
+ return (ENXIO);
+ }
+
+ /* apm0 only */
+ if (APMUNIT(dev) != 0)
+ return (ENODEV);
+
+ sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0];
+
+ switch (kn->kn_filter) {
+ case EVFILT_READ:
+ kn->kn_fop = &apmread_filtops;
+ break;
+ default:
+ return (1);
+ }
+
+ kn->kn_hook = (caddr_t)sc;
+ SLIST_INSERT_HEAD(&sc->sc_note, kn, kn_selnext);
+
+ return (0);
+}
diff --git a/sys/arch/sparc/dev/ts102reg.h b/sys/arch/sparc/dev/ts102reg.h
index e03b6954214..e42a2ecf4e0 100644
--- a/sys/arch/sparc/dev/ts102reg.h
+++ b/sys/arch/sparc/dev/ts102reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ts102reg.h,v 1.3 2003/06/18 17:50:23 miod Exp $ */
+/* $OpenBSD: ts102reg.h,v 1.4 2005/03/29 16:26:44 miod Exp $ */
/* $NetBSD: ts102reg.h,v 1.7 2002/09/29 23:23:58 wiz Exp $ */
/*-
@@ -348,6 +348,7 @@ enum ts102_opcode { /* Argument Returned */
TS102_OP_ADMIN_VRFY_SYSTEM_PASS=0x73, /* len <pass> ack + status */
TS102_OP_RD_INT_CHARGE_LEVEL=0x7a, /* ack + 2 byte */
TS102_OP_RD_EXT_CHARGE_LEVEL=0x7b, /* ack + 2 byte */
+#define TS102_CHARGE_UNKNOWN 0xfa
TS102_OP_SLEEP=0x80, /* supposedly sleeps, not sure */
TS102_OP_ADMIN_POWER_OFF=0x82, /* len <pass> none */
TS102_OP_ADMIN_POWER_RESTART=0x83, /* msb,xx,lsb none */
diff --git a/sys/arch/sparc/include/apmvar.h b/sys/arch/sparc/include/apmvar.h
new file mode 100644
index 00000000000..44404357b8f
--- /dev/null
+++ b/sys/arch/sparc/include/apmvar.h
@@ -0,0 +1,124 @@
+/* $OpenBSD: apmvar.h,v 1.1 2005/03/29 16:26:44 miod Exp $ */
+
+/*
+ * Copyright (c) 1995 John T. Kohl
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `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 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.
+ *
+ */
+#ifndef _MACHINE_APMVAR_H_
+#define _MACHINE_APMVAR_H_
+
+#include <sys/ioccom.h>
+
+/*
+ * This is a subset of the Advanced Power Management (v1.0 and v1.1
+ * specification) functions/defines/etc, covering the abilities of
+ * the tctrl driver.
+ */
+
+#define APM_POWER_STATUS 0x530a
+#define APM_AC_OFF 0x00
+#define APM_AC_ON 0x01
+#define APM_AC_BACKUP 0x02
+#define APM_AC_UNKNOWN 0xff
+#define APM_BATT_HIGH 0x00
+#define APM_BATT_LOW 0x01
+#define APM_BATT_CRITICAL 0x02
+#define APM_BATT_CHARGING 0x03
+#define APM_BATT_UNKNOWN 0xff
+#define APM_BATT_FLAG_HIGH 0x01
+#define APM_BATT_FLAG_LOW 0x02
+#define APM_BATT_FLAG_CRITICAL 0x04
+#define APM_BATT_FLAG_CHARGING 0x08
+#define APM_BATT_FLAG_NOBATTERY 0x10
+#define APM_BATT_FLAG_NOSYSBATT 0x80
+#define APM_BATT_LIFE_UNKNOWN 0xff
+
+#define APM_GET_PM_EVENT 0x530b
+#define APM_NOEVENT 0x0000
+#define APM_STANDBY_REQ 0x0001 /* %bx on return */
+#define APM_SUSPEND_REQ 0x0002
+#define APM_NORMAL_RESUME 0x0003
+#define APM_CRIT_RESUME 0x0004 /* suspend/resume happened
+ without us */
+#define APM_BATTERY_LOW 0x0005
+#define APM_POWER_CHANGE 0x0006
+#define APM_UPDATE_TIME 0x0007
+#define APM_CRIT_SUSPEND_REQ 0x0008
+#define APM_USER_STANDBY_REQ 0x0009
+#define APM_USER_SUSPEND_REQ 0x000A
+#define APM_SYS_STANDBY_RESUME 0x000B
+#define APM_CAPABILITY_CHANGE 0x000C /* apm v1.2 */
+
+#define APM_EVENT_MASK 0xffff
+
+#define APM_EVENT_COMPOSE(t,i) ((((i) & 0x7fff) << 16)|((t) & APM_EVENT_MASK))
+#define APM_EVENT_TYPE(e) ((e) & APM_EVENT_MASK)
+#define APM_EVENT_INDEX(e) ((e) >> 16)
+
+#define APM_GET_POWER_STATE 0x530c
+
+/*
+ * LP (Laptop Package)
+ *
+ * Copyright (C) 1994 by HOSOKAWA Tatsumi <hosokawa@mt.cs.keio.ac.jp>
+ *
+ * This software may be used, modified, copied, and distributed, in
+ * both source and binary form provided that the above copyright and
+ * these terms are retained. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with its
+ * use.
+ *
+ * Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
+ */
+
+#define APM_BATTERY_ABSENT 4
+
+struct apm_power_info {
+ u_char battery_state;
+ u_char ac_state;
+ u_char battery_life;
+ u_char spare1;
+ u_int minutes_left; /* estimate */
+ u_int spare2[6];
+};
+
+struct apm_ctl {
+ u_int dev;
+ u_int mode;
+};
+
+#define APM_IOC_STANDBY _IO('A', 1) /* put system into standby */
+#define APM_IOC_SUSPEND _IO('A', 2) /* put system into suspend */
+#define APM_IOC_GETPOWER _IOR('A', 3, struct apm_power_info) /* fetch battery state */
+#define APM_IOC_PRN_CTL _IOW('A', 6, int) /* driver power status msg */
+#define APM_PRINT_ON 0 /* driver power status displayed */
+#define APM_PRINT_OFF 1 /* driver power status not displayed */
+#define APM_PRINT_PCT 2 /* driver power status only displayed
+ if the percentage changes */
+
+#endif /* _MACHINE_APMVAR_H_ */
diff --git a/sys/arch/sparc/include/conf.h b/sys/arch/sparc/include/conf.h
index ee7e8d4298c..ca6a9d746b3 100644
--- a/sys/arch/sparc/include/conf.h
+++ b/sys/arch/sparc/include/conf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.h,v 1.18 2003/09/23 16:51:11 millert Exp $ */
+/* $OpenBSD: conf.h,v 1.19 2005/03/29 16:26:44 miod Exp $ */
/* $NetBSD: conf.h,v 1.8 1996/12/31 07:12:43 mrg Exp $ */
/*
@@ -105,3 +105,11 @@ cdev_decl(fga);
(dev_type_stop((*))) nullop, 0, seltrue, \
(dev_type_mmap((*))) enodev }
cdev_decl(daadio);
+
+/* open, close, write, ioctl, kqueue */
+#define cdev_apm_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
+ (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
+ (dev_type_stop((*))) enodev, 0, (dev_type_poll((*))) enodev, \
+ (dev_type_mmap((*))) enodev, D_KQFILTER, dev_init(c,n,kqfilter) }
+cdev_decl(apm);
diff --git a/sys/arch/sparc/sparc/conf.c b/sys/arch/sparc/sparc/conf.c
index d31d1b9ef47..b28d6eb002e 100644
--- a/sys/arch/sparc/sparc/conf.c
+++ b/sys/arch/sparc/sparc/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.39 2004/02/10 01:31:21 millert Exp $ */
+/* $OpenBSD: conf.c,v 1.40 2005/03/29 16:26:45 miod Exp $ */
/* $NetBSD: conf.c,v 1.40 1996/04/11 19:20:03 thorpej Exp $ */
/*
@@ -125,8 +125,8 @@ struct bdevsw bdevsw[] =
int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]);
#include "pf.h"
-
#include "systrace.h"
+#include "tctrl.h"
struct cdevsw cdevsw[] =
{
@@ -160,7 +160,7 @@ struct cdevsw cdevsw[] =
cdev_notdef(), /* 27: was /dev/bwtwo */
cdev_notdef(), /* 28 */
cdev_notdef(), /* 29: was /dev/kbd */
- cdev_notdef(), /* 30 */
+ cdev_apm_init(NTCTRL,apm), /* 30: tctrl APM interface */
cdev_notdef(), /* 31: was /dev/cgtwo */
cdev_notdef(), /* 32: should be /dev/gpone */
cdev_notdef(), /* 33 */
diff --git a/usr.sbin/apm/Makefile b/usr.sbin/apm/Makefile
index fed9fcad116..484a0038245 100644
--- a/usr.sbin/apm/Makefile
+++ b/usr.sbin/apm/Makefile
@@ -1,8 +1,8 @@
-# $OpenBSD: Makefile,v 1.9 2005/02/21 21:59:40 uwe Exp $
+# $OpenBSD: Makefile,v 1.10 2005/03/29 16:26:45 miod Exp $
.if (${MACHINE} == "i386") || (${MACHINE} == "macppc") || \
- (${MACHINE} == "zaurus")
+ (${MACHINE} == "sparc") || (${MACHINE} == "zaurus")
SRCS= apm.c apmsubr.c
.PATH: ${.CURDIR}/../apmd
@@ -15,7 +15,7 @@ NOPROG=yes
.endif
MAN= apm.8
-MANSUBDIR=i386 macppc zaurus
+MANSUBDIR=i386 macppc sparc zaurus
MLINKS= apm.8 zzz.8
.include <bsd.prog.mk>
diff --git a/usr.sbin/apmd/Makefile b/usr.sbin/apmd/Makefile
index 5fd01009143..d5754a377e8 100644
--- a/usr.sbin/apmd/Makefile
+++ b/usr.sbin/apmd/Makefile
@@ -1,7 +1,7 @@
-# $OpenBSD: Makefile,v 1.7 2005/01/19 02:02:34 uwe Exp $
+# $OpenBSD: Makefile,v 1.8 2005/03/29 16:26:45 miod Exp $
.if (${MACHINE} == "i386") || (${MACHINE} == "macppc") || \
- (${MACHINE} == "zaurus")
+ (${MACHINE} == "sparc") || (${MACHINE} == "zaurus")
SRCS= apmd.c apmsubr.c
PROG= apmd
@@ -10,6 +10,6 @@ NOPROG=yes
.endif
MAN= apmd.8
-MANSUBDIR=i386 macppc zaurus
+MANSUBDIR=i386 macppc sparc zaurus
.include <bsd.prog.mk>