summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorUwe Stuehler <uwe@cvs.openbsd.org>2005-01-19 02:02:35 +0000
committerUwe Stuehler <uwe@cvs.openbsd.org>2005-01-19 02:02:35 +0000
commit01f308907b3edaf28e20dfb3875d2cb969b1b185 (patch)
treed24de5076140afc7ae4c23f89422ea87a23303e3 /sys
parent9b80c4fe9ef02d77bb4d2cedf41da21bdaaec693 (diff)
APM emulation framework and zaurus scoop driver. Not enabled yet.
ok drahn@, deraadt@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/arm/arm/conf.c13
-rw-r--r--sys/arch/arm/include/apmvar.h118
-rw-r--r--sys/arch/arm/xscale/files.pxa2x07
-rw-r--r--sys/arch/arm/xscale/pxa2x0_apm.c471
-rw-r--r--sys/arch/arm/xscale/pxa2x0_apm.h38
-rw-r--r--sys/arch/zaurus/conf/GENERIC7
-rw-r--r--sys/arch/zaurus/conf/RAMDISK7
-rw-r--r--sys/arch/zaurus/conf/files.zaurus7
-rw-r--r--sys/arch/zaurus/dev/zaurus_scoop.c123
-rw-r--r--sys/arch/zaurus/dev/zaurus_scoopreg.h15
-rw-r--r--sys/arch/zaurus/dev/zaurus_scoopvar.h10
-rw-r--r--sys/arch/zaurus/include/apmvar.h1
-rw-r--r--sys/arch/zaurus/include/conf.h14
13 files changed, 824 insertions, 7 deletions
diff --git a/sys/arch/arm/arm/conf.c b/sys/arch/arm/arm/conf.c
index d8a78efd272..23c2bc78cd2 100644
--- a/sys/arch/arm/arm/conf.c
+++ b/sys/arch/arm/arm/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.9 2005/01/18 16:27:26 drahn Exp $ */
+/* $OpenBSD: conf.c,v 1.10 2005/01/19 02:02:33 uwe Exp $ */
/* $NetBSD: conf.c,v 1.10 2002/04/19 01:04:38 wiz Exp $ */
/*
@@ -76,6 +76,15 @@
#include "ksyms.h"
/*
+ * APM interface
+ */
+#ifdef CONF_HAVE_APM
+#include "apm.h"
+#else
+#define NAPM 0
+#endif
+
+/*
* Disk/Filesystem pseudo-devices
*/
#include "ccd.h" /* concatenated disk driver */
@@ -304,7 +313,7 @@ struct cdevsw cdevsw[] = {
cdev_lkm_dummy(), /* 31: */
cdev_lkm_dummy(), /* 32: */
cdev_bpftun_init(NTUN,tun), /* 33: network tunnel */
- cdev_lkm_dummy(), /* 34: */
+ cdev_apm_init(NAPM,apm), /* 34: APM interface */
cdev_lkm_init(NLKM,lkm), /* 35: loadable module driver */
cdev_audio_init(NAUDIO,audio), /* 36: generic audio I/O */
cdev_hotplug_init(NHOTPLUG,hotplug), /* 37: devices hot plugging*/
diff --git a/sys/arch/arm/include/apmvar.h b/sys/arch/arm/include/apmvar.h
new file mode 100644
index 00000000000..57547b5a36a
--- /dev/null
+++ b/sys/arch/arm/include/apmvar.h
@@ -0,0 +1,118 @@
+/* $OpenBSD: apmvar.h,v 1.1 2005/01/19 02:02:34 uwe Exp $ */
+
+/*
+ * Copyright (c) 2001 Alexander Guy
+ * 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 _ARM_APMVAR_H_
+#define _ARM_APMVAR_H_
+
+#include <sys/ioccom.h>
+
+/* Advanced Power Management (v1.0 and v1.1 specification)
+ * functions/defines/etc.
+ */
+
+/* These definitions make up the heart of the user-land interface
+ * to the APM devices.
+ */
+
+#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_LIFE_UNKNOWN 0xff
+
+#define APM_NOEVENT 0x0000
+#define APM_STANDBY_REQ 0x0001
+#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)
+
+/*
+ * 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_REJECT _IOW('A', 0, struct apm_event_info) /* reject request # */
+#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_DEV_CTL _IOW('A', 5, struct apm_ctl) /* put device into mode */
+#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 /* _ARM_APMVAR_H_ */
diff --git a/sys/arch/arm/xscale/files.pxa2x0 b/sys/arch/arm/xscale/files.pxa2x0
index 08f9ada7fa5..b15530901eb 100644
--- a/sys/arch/arm/xscale/files.pxa2x0
+++ b/sys/arch/arm/xscale/files.pxa2x0
@@ -1,4 +1,4 @@
-# $OpenBSD: files.pxa2x0,v 1.4 2005/01/04 03:47:00 drahn Exp $
+# $OpenBSD: files.pxa2x0,v 1.5 2005/01/19 02:02:34 uwe Exp $
# $NetBSD: files.pxa2x0,v 1.6 2004/05/01 19:09:14 thorpej Exp $
#
# Configuration info for Intel PXA2[51]0 CPU support
@@ -51,6 +51,11 @@ file arch/arm/xscale/pxa2x0_ohci.c pxaohci
device lcd: wsemuldisplaydev, rasops16, rasops8, rasops4
file arch/arm/xscale/pxa2x0_lcd.c lcd needs-flag
+# Power manager and APM emulation
+device apm
+attach apm at pxaip
+file arch/arm/xscale/pxa2x0_apm.c apm needs-flag
+
include "dev/pcmcia/files.pcmcia"
# PCMCIA controller
diff --git a/sys/arch/arm/xscale/pxa2x0_apm.c b/sys/arch/arm/xscale/pxa2x0_apm.c
new file mode 100644
index 00000000000..5d47c7e39d2
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0_apm.c
@@ -0,0 +1,471 @@
+/* $OpenBSD: pxa2x0_apm.c,v 1.1 2005/01/19 02:02:34 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2001 Alexander Guy. All rights reserved.
+ * 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/kernel.h>
+#include <sys/kthread.h>
+#include <sys/lock.h>
+#include <sys/mount.h> /* for vfs_syncwait() */
+#include <sys/proc.h>
+#include <sys/device.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/event.h>
+
+#include <machine/conf.h>
+#include <machine/cpu.h>
+#include <machine/apmvar.h>
+
+#include <arm/xscale/pxa2x0reg.h>
+#include <arm/xscale/pxa2x0var.h>
+#include <arm/xscale/pxa2x0_apm.h>
+
+#if defined(APMDEBUG)
+#define DPRINTF(x) printf x
+#else
+#define DPRINTF(x) /**/
+#endif
+
+#define APM_LOCK(sc) lockmgr(&(sc)->sc_lock, LK_EXCLUSIVE, NULL, curproc)
+#define APM_UNLOCK(sc) lockmgr(&(sc)->sc_lock, LK_RELEASE, NULL, curproc)
+
+int apmmatch(struct device *, void *, void *);
+void apmattach(struct device *, struct device *, void *);
+
+struct cfattach apm_ca = {
+ sizeof(struct pxa2x0_apm_softc), apmmatch, apmattach
+};
+
+struct cfdriver apm_cd = {
+ NULL, "apm", DV_DULL
+};
+
+#define APMUNIT(dev) (minor(dev)&0xf0)
+#define APMDEV(dev) (minor(dev)&0x0f)
+#define APMDEV_NORMAL 0
+#define APMDEV_CTL 8
+
+int apm_userstandbys;
+int apm_suspends;
+int apm_battlow;
+
+void apm_standby(struct pxa2x0_apm_softc *);
+void apm_suspend(struct pxa2x0_apm_softc *);
+void apm_resume(struct pxa2x0_apm_softc *);
+void apm_periodic_check(struct pxa2x0_apm_softc *);
+void apm_thread_create(void *);
+void apm_thread(void *);
+
+void pxa2x0_apm_standby(struct pxa2x0_apm_softc *);
+void pxa2x0_apm_sleep(struct pxa2x0_apm_softc *);
+
+void filt_apmrdetach(struct knote *kn);
+int filt_apmread(struct knote *kn, long hint);
+int apmkqfilter(dev_t dev, struct knote *kn);
+
+struct filterops apmread_filtops =
+ { 1, NULL, filt_apmrdetach, filt_apmread};
+
+/*
+ * 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)
+
+#define SCFLAG_OREAD (1 << 0)
+#define SCFLAG_OWRITE (1 << 1)
+#define SCFLAG_OPEN (SCFLAG_OREAD|SCFLAG_OWRITE)
+
+int
+apmmatch(struct device *parent, void *match, void *aux)
+{
+ return 1;
+}
+
+void
+apmattach(struct device *parent, struct device *self, void *aux)
+{
+ struct pxa2x0_apm_softc *sc = (struct pxa2x0_apm_softc *)self;
+
+ pxa2x0_apm_attach_sub((struct pxa2x0_apm_softc *)sc);
+}
+
+void
+apm_standby(struct pxa2x0_apm_softc *sc)
+{
+
+ dopowerhooks(PWR_STANDBY);
+
+ if (cold)
+ vfs_syncwait(0);
+
+ pxa2x0_apm_standby((struct pxa2x0_apm_softc *)sc);
+}
+
+void
+apm_suspend(struct pxa2x0_apm_softc *sc)
+{
+
+#if 0
+ /* XXX something is not restored in PWR_RESUME. */
+ dopowerhooks(PWR_SUSPEND);
+#else
+ dopowerhooks(PWR_STANDBY);
+#endif
+
+ if (cold)
+ vfs_syncwait(0);
+
+ pxa2x0_apm_sleep((struct pxa2x0_apm_softc *)sc);
+}
+
+void
+apm_resume(struct pxa2x0_apm_softc *sc)
+{
+
+ dopowerhooks(PWR_RESUME);
+}
+
+void
+apm_periodic_check(struct pxa2x0_apm_softc *sc)
+{
+
+ if (apm_suspends) {
+ apm_userstandbys = 0;
+ apm_suspends = 0;
+ apm_suspend(sc);
+ apm_resume(sc);
+ } else if (apm_userstandbys) {
+ apm_userstandbys = 0;
+ apm_standby(sc);
+ apm_resume(sc);
+ }
+}
+
+void
+apm_thread_create(void *v)
+{
+ struct pxa2x0_apm_softc *sc = v;
+
+ if (kthread_create(apm_thread, sc, &sc->sc_thread,
+ "%s", sc->sc_dev.dv_xname)) {
+ /* apm_disconnect(sc); */
+ printf("%s: failed to create kernel thread, disabled",
+ sc->sc_dev.dv_xname);
+ }
+}
+
+void
+apm_thread(void *v)
+{
+ struct pxa2x0_apm_softc *sc = v;
+
+ for (;;) {
+ APM_LOCK(sc);
+ apm_periodic_check(sc);
+ APM_UNLOCK(sc);
+ tsleep(&lbolt, PWAIT, "apmev", 0);
+ }
+}
+
+int
+apmopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ struct pxa2x0_apm_softc *sc;
+ int error = 0;
+
+ /* apm0 only */
+ if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
+ !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
+ return ENXIO;
+
+ DPRINTF(("apmopen: dev %d pid %d flag %x mode %x\n",
+ APMDEV(dev), p->p_pid, flag, mode));
+
+ switch (APMDEV(dev)) {
+ case APMDEV_CTL:
+ if (!(flag & FWRITE)) {
+ error = EINVAL;
+ break;
+ }
+ if (sc->sc_flags & SCFLAG_OWRITE) {
+ error = EBUSY;
+ break;
+ }
+ sc->sc_flags |= SCFLAG_OWRITE;
+ break;
+ case APMDEV_NORMAL:
+ if (!(flag & FREAD) || (flag & FWRITE)) {
+ error = EINVAL;
+ break;
+ }
+ sc->sc_flags |= SCFLAG_OREAD;
+ break;
+ default:
+ error = ENXIO;
+ break;
+ }
+ return error;
+}
+
+int
+apmclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ struct pxa2x0_apm_softc *sc;
+
+ /* apm0 only */
+ if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
+ !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
+ return ENXIO;
+
+ DPRINTF(("apmclose: pid %d flag %x mode %x\n", p->p_pid, flag, mode));
+
+ switch (APMDEV(dev)) {
+ case APMDEV_CTL:
+ sc->sc_flags &= ~SCFLAG_OWRITE;
+ break;
+ case APMDEV_NORMAL:
+ sc->sc_flags &= ~SCFLAG_OREAD;
+ break;
+ }
+ return 0;
+}
+
+int
+apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct pxa2x0_apm_softc *sc;
+#if 0
+ struct pmu_battery_info batt;
+#endif
+ struct apm_power_info *power;
+ int error = 0;
+
+ /* apm0 only */
+ if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
+ !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
+ return ENXIO;
+
+ switch (cmd) {
+ /* some ioctl names from linux */
+ case APM_IOC_STANDBY:
+ if ((flag & FWRITE) == 0)
+ error = EBADF;
+ else
+ apm_userstandbys++;
+ break;
+ case APM_IOC_SUSPEND:
+ if ((flag & FWRITE) == 0)
+ error = EBADF;
+ else
+ apm_suspends++; /* XXX */
+ break;
+ case APM_IOC_PRN_CTL:
+ if ((flag & FWRITE) == 0)
+ error = EBADF;
+ else {
+ int flag = *(int *)data;
+ DPRINTF(( "APM_IOC_PRN_CTL: %d\n", flag ));
+ switch (flag) {
+ case APM_PRINT_ON: /* enable printing */
+ sc->sc_flags &= ~SCFLAG_PRINT;
+ break;
+ case APM_PRINT_OFF: /* disable printing */
+ sc->sc_flags &= ~SCFLAG_PRINT;
+ sc->sc_flags |= SCFLAG_NOPRINT;
+ break;
+ case APM_PRINT_PCT: /* disable some printing */
+ sc->sc_flags &= ~SCFLAG_PRINT;
+ sc->sc_flags |= SCFLAG_PCTPRINT;
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ }
+ break;
+ case APM_IOC_DEV_CTL:
+ if ((flag & FWRITE) == 0)
+ error = EBADF;
+ break;
+ case APM_IOC_GETPOWER:
+ power = (struct apm_power_info *)data;
+
+#if 0
+ pm_battery_info(0, &batt);
+
+ power->ac_state = ((batt.flags & PMU_PWR_AC_PRESENT) ?
+ APM_AC_ON : APM_AC_OFF);
+ power->battery_life =
+ ((batt.cur_charge * 100) / batt.max_charge);
+#else
+ power->ac_state = APM_AC_ON;
+ power->battery_life = 100;
+#endif
+
+ /*
+ * If the battery is charging, return the minutes left until
+ * charging is complete. apmd knows this.
+ */
+
+#if 0
+ if (!(batt.flags & PMU_PWR_BATT_PRESENT)) {
+ power->battery_state = APM_BATT_UNKNOWN;
+ power->minutes_left = 0;
+ power->battery_life = 0;
+ } else if ((power->ac_state == APM_AC_ON) &&
+ (batt.draw > 0)) {
+ power->minutes_left =
+ (((batt.max_charge - batt.cur_charge) * 3600) /
+ batt.draw) / 60;
+ power->battery_state = APM_BATT_CHARGING;
+ } else {
+ power->minutes_left =
+ ((batt.cur_charge * 3600) / (-batt.draw)) / 60;
+
+ /* XXX - Arbitrary */
+ if (power->battery_life > 60)
+ power->battery_state = APM_BATT_HIGH;
+ else if (power->battery_life < 10)
+ power->battery_state = APM_BATT_CRITICAL;
+ else
+ power->battery_state = APM_BATT_LOW;
+ }
+#else
+ power->battery_state = APM_BATT_UNKNOWN;
+ power->minutes_left = 0;
+ power->battery_life = 0;
+#endif
+ break;
+
+ default:
+ error = ENOTTY;
+ }
+
+ return error;
+}
+
+void
+filt_apmrdetach(struct knote *kn)
+{
+ struct pxa2x0_apm_softc *sc =
+ (struct pxa2x0_apm_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 pxa2x0_apm_softc *sc;
+
+ /* apm0 only */
+ if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
+ !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
+ return ENXIO;
+
+ 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);
+}
+
+void
+pxa2x0_apm_standby(struct pxa2x0_apm_softc *sc)
+{
+ int save;
+
+ save = disable_interrupts(I32_bit|F32_bit);
+
+ /* XXX add power hooks elsewhere, first. */
+
+ restore_interrupts(save);
+}
+
+void
+pxa2x0_apm_sleep(struct pxa2x0_apm_softc *sc)
+{
+
+ /* XXX first make standby work, and then sleep mode. */
+ pxa2x0_apm_standby(sc);
+}
+
+void
+pxa2x0_apm_attach_sub(struct pxa2x0_apm_softc *sc)
+{
+
+ sc->sc_iot = &pxa2x0_bs_tag;
+
+ if (bus_space_map(sc->sc_iot, PXA2X0_POWMAN_BASE,
+ PXA2X0_POWMAN_SIZE, 0, &sc->sc_pm_ioh)) {
+ printf("pxa2x0_apm_attach_sub: failed to map POWMAN\n");
+ return;
+ }
+
+ lockinit(&sc->sc_lock, PWAIT, "apmlk", 0, 0);
+
+ kthread_create_deferred(apm_thread_create, sc);
+
+ printf("\n");
+}
diff --git a/sys/arch/arm/xscale/pxa2x0_apm.h b/sys/arch/arm/xscale/pxa2x0_apm.h
new file mode 100644
index 00000000000..61cd37c92e5
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0_apm.h
@@ -0,0 +1,38 @@
+/* $OpenBSD: pxa2x0_apm.h,v 1.1 2005/01/19 02:02:34 uwe Exp $ */
+
+/*
+ * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _PXA2X0_APM_H_
+#define _PXA2X0_APM_H_
+
+#include <sys/event.h>
+
+#include <machine/bus.h>
+
+struct pxa2x0_apm_softc {
+ struct device sc_dev;
+ struct proc *sc_thread;
+ struct lock sc_lock;
+ struct klist sc_note;
+ int sc_flags;
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_pm_ioh;
+};
+
+extern void pxa2x0_apm_attach_sub(struct pxa2x0_apm_softc *);
+
+#endif
diff --git a/sys/arch/zaurus/conf/GENERIC b/sys/arch/zaurus/conf/GENERIC
index f2180b643e2..d1d9e035b92 100644
--- a/sys/arch/zaurus/conf/GENERIC
+++ b/sys/arch/zaurus/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.20 2005/01/18 17:57:57 drahn Exp $
+# $OpenBSD: GENERIC,v 1.21 2005/01/19 02:02:34 uwe Exp $
#
# GENERIC machine description file
#
@@ -60,6 +60,8 @@ pxaip0 at mainbus?
pxaintc0 at pxaip? # interrupt controller
pxagpio0 at pxaip? # GPIO
+#scoop0 at pxaip? addr 0x10800000 size 0x2c
+#scoop1 at pxaip? addr 0x14800000 size 0x2c
saost0 at pxaip? addr 0x40a00000 size 0x20
ohci0 at pxaip? addr 0x4c000000 size 0x70 intr 3
usb* at ohci?
@@ -180,6 +182,9 @@ ukphy* at mii? # "unknown" PHYs
lcd0 at pxaip?
wsdisplay* at lcd? console ?
+# APM emulation
+#apm0 at pxaip?
+
# Pseudo-Devices
pseudo-device wsmux 2 # mouse & keyboard multiplexor
pseudo-device crypto 1
diff --git a/sys/arch/zaurus/conf/RAMDISK b/sys/arch/zaurus/conf/RAMDISK
index f6ce095d229..dc500a93516 100644
--- a/sys/arch/zaurus/conf/RAMDISK
+++ b/sys/arch/zaurus/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.15 2005/01/17 22:58:01 miod Exp $
+# $OpenBSD: RAMDISK,v 1.16 2005/01/19 02:02:34 uwe Exp $
#
# GENERIC machine description file
#
@@ -66,6 +66,8 @@ pxaip0 at mainbus?
pxaintc0 at pxaip? # interrupt controller
pxagpio0 at pxaip? # GPIO
+#scoop0 at pxaip? addr 0x10800000 size 0x2c
+#scoop1 at pxaip? addr 0x14800000 size 0x2c
saost0 at pxaip? addr 0x40a00000 size 0x20
ohci0 at pxaip? addr 0x4c000000 size 0x70 intr 3
usb* at ohci?
@@ -160,6 +162,9 @@ ukphy* at mii? # "unknown" PHYs
lcd0 at pxaip?
wsdisplay* at lcd? console ?
+# APM emulation
+#apm0 at pxaip?
+
# Pseudo-Devices
pseudo-device wsmux 2 # mouse & keyboard multiplexor
#pseudo-device crypto 1
diff --git a/sys/arch/zaurus/conf/files.zaurus b/sys/arch/zaurus/conf/files.zaurus
index e2d01a1766d..e14ff5b196f 100644
--- a/sys/arch/zaurus/conf/files.zaurus
+++ b/sys/arch/zaurus/conf/files.zaurus
@@ -1,4 +1,4 @@
-# $OpenBSD: files.zaurus,v 1.11 2005/01/16 18:13:10 deraadt Exp $
+# $OpenBSD: files.zaurus,v 1.12 2005/01/19 02:02:34 uwe Exp $
#
# First try for arm-specific configuration info
#
@@ -33,6 +33,11 @@ device zkbd: wskbddev
attach zkbd at pxaip
file arch/zaurus/dev/zaurus_kbd.c zkbd
+# Onboard peripheral and GPIO controller
+device scoop
+attach scoop at pxaip with scoop_pxaip
+file arch/zaurus/dev/zaurus_scoop.c scoop
+
#
# Machine-independent ATA drivers
#
diff --git a/sys/arch/zaurus/dev/zaurus_scoop.c b/sys/arch/zaurus/dev/zaurus_scoop.c
new file mode 100644
index 00000000000..e1dab6f6792
--- /dev/null
+++ b/sys/arch/zaurus/dev/zaurus_scoop.c
@@ -0,0 +1,123 @@
+/* $OpenBSD: zaurus_scoop.c,v 1.1 2005/01/19 02:02:34 uwe Exp $ */
+
+/*
+ * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+
+#include <machine/bus.h>
+
+#include <arm/xscale/pxa2x0var.h>
+
+#include <zaurus/dev/zaurus_scoopreg.h>
+#include <zaurus/dev/zaurus_scoopvar.h>
+
+int scoopmatch(struct device *, void *, void *);
+void scoopattach(struct device *, struct device *, void *);
+
+struct cfattach scoop_pxaip_ca = {
+ sizeof (struct scoop_softc), scoopmatch, scoopattach
+};
+
+struct cfdriver scoop_cd = {
+ NULL, "scoop", DV_DULL
+};
+
+/* GPIO pin/bit numbers for the Zaurus C3000. */
+#define SCOOP1_BACKLIGHT_ON 8
+
+struct scoop_softc *scoop0_sc;
+struct scoop_softc *scoop1_sc;
+int nscoopunits = 0;
+
+
+int
+scoopmatch(struct device *parent, void *cf, void *aux)
+{
+ struct pxaip_attach_args *pxa = aux;
+
+ if (pxa->pxa_addr == -1)
+ return 0;
+
+ /*
+ * Only the C3000 models (pxa270) are known to have two SCOOPs,
+ * on other models we only find the first one.
+ */
+ if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X)
+ return (nscoopunits < 2);
+
+ return (nscoopunits < 1);
+}
+
+void
+scoopattach(struct device *parent, struct device *self, void *aux)
+{
+ struct pxaip_attach_args *pxa = aux;
+ struct scoop_softc *sc = (struct scoop_softc *)self;
+ bus_size_t size;
+
+ nscoopunits++;
+
+ sc->sc_iot = pxa->pxa_iot;
+ size = pxa->pxa_size < SCOOP_SIZE ? SCOOP_SIZE : pxa->pxa_size;
+
+ if (bus_space_map(sc->sc_iot, pxa->pxa_addr, size, 0,
+ &sc->sc_ioh) != 0) {
+ printf(": failed to map SCOOP%d\n", nscoopunits - 1);
+ return;
+ }
+
+ printf(": Onboard Peripheral Controller\n");
+
+ if (nscoopunits == 1)
+ scoop0_sc = sc;
+ else if (nscoopunits == 2)
+ scoop1_sc = sc;
+}
+
+int
+scoop_gpio_pin_read(struct scoop_softc *sc, int pin)
+{
+ unsigned short rv;
+ unsigned short bit = (1 << pin);
+
+ rv = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SCOOP_GPWR);
+ return (rv & bit) != 0 ? 1 : 0;
+}
+
+void
+scoop_gpio_pin_write(struct scoop_softc *sc, int pin, int value)
+{
+ unsigned short rv;
+ unsigned short bit = (1 << pin);
+
+ rv = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SCOOP_GPWR);
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, SCOOP_GPWR,
+ value != 0 ? (rv | bit) : (rv & ~bit));
+}
+
+void
+scoop_backlight_on(int enable)
+{
+
+#if 0 /* XXX no effect. maybe the pin is incorrectly configured? */
+ if (scoop1_sc != (struct scoop_softc *)0)
+ scoop_gpio_pin_write(scoop1_sc, SCOOP1_BACKLIGHT_ON,
+ enable);
+#endif
+}
diff --git a/sys/arch/zaurus/dev/zaurus_scoopreg.h b/sys/arch/zaurus/dev/zaurus_scoopreg.h
new file mode 100644
index 00000000000..83e982fdf5a
--- /dev/null
+++ b/sys/arch/zaurus/dev/zaurus_scoopreg.h
@@ -0,0 +1,15 @@
+
+#define SCOOP_SIZE 0x2c
+
+#define SCOOP_MCR 0x00
+#define SCOOP_CDR 0x04
+#define SCOOP_CSR 0x08
+#define SCOOP_CPR 0x0c
+#define SCOOP_CCR 0x10
+#define SCOOP_IRR 0x14
+#define SCOOP_IRM 0x14
+#define SCOOP_IMR 0x18
+#define SCOOP_ISR 0x1c
+#define SCOOP_GPCR 0x20
+#define SCOOP_GPWR 0x24
+#define SCOOP_GPRR 0x28
diff --git a/sys/arch/zaurus/dev/zaurus_scoopvar.h b/sys/arch/zaurus/dev/zaurus_scoopvar.h
new file mode 100644
index 00000000000..13ea3461fb2
--- /dev/null
+++ b/sys/arch/zaurus/dev/zaurus_scoopvar.h
@@ -0,0 +1,10 @@
+struct scoop_softc {
+ struct device sc_dev;
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+};
+
+extern void scoop_backlight_on(int);
+
+extern int scoop_gpio_pin_read(struct scoop_softc *sc, int);
+extern void scoop_gpio_pin_write(struct scoop_softc *sc, int, int);
diff --git a/sys/arch/zaurus/include/apmvar.h b/sys/arch/zaurus/include/apmvar.h
new file mode 100644
index 00000000000..dfce83ed6c6
--- /dev/null
+++ b/sys/arch/zaurus/include/apmvar.h
@@ -0,0 +1 @@
+#include <arm/apmvar.h>
diff --git a/sys/arch/zaurus/include/conf.h b/sys/arch/zaurus/include/conf.h
index aa820d703cc..61f2c2d1036 100644
--- a/sys/arch/zaurus/include/conf.h
+++ b/sys/arch/zaurus/include/conf.h
@@ -1,16 +1,28 @@
-/* $OpenBSD: conf.h,v 1.4 2005/01/04 14:13:06 drahn Exp $ */
+/* $OpenBSD: conf.h,v 1.5 2005/01/19 02:02:34 uwe Exp $ */
/* $NetBSD: conf.h,v 1.8 2002/02/10 12:26:03 chris Exp $ */
#ifndef _ZAURUS_CONF_H
#define _ZAURUS_CONF_H
+#include <sys/conf.h>
+
/*
* ZAURUS specific device includes go in here
*/
+#define CONF_HAVE_APM
#define CONF_HAVE_USB
#define CONF_HAVE_WSCONS
#include <arm/conf.h>
+/* 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);
+
#endif /* _ZAURUS_CONF_H */