diff options
author | Uwe Stuehler <uwe@cvs.openbsd.org> | 2005-01-19 02:02:35 +0000 |
---|---|---|
committer | Uwe Stuehler <uwe@cvs.openbsd.org> | 2005-01-19 02:02:35 +0000 |
commit | 01f308907b3edaf28e20dfb3875d2cb969b1b185 (patch) | |
tree | d24de5076140afc7ae4c23f89422ea87a23303e3 /sys | |
parent | 9b80c4fe9ef02d77bb4d2cedf41da21bdaaec693 (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.c | 13 | ||||
-rw-r--r-- | sys/arch/arm/include/apmvar.h | 118 | ||||
-rw-r--r-- | sys/arch/arm/xscale/files.pxa2x0 | 7 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxa2x0_apm.c | 471 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxa2x0_apm.h | 38 | ||||
-rw-r--r-- | sys/arch/zaurus/conf/GENERIC | 7 | ||||
-rw-r--r-- | sys/arch/zaurus/conf/RAMDISK | 7 | ||||
-rw-r--r-- | sys/arch/zaurus/conf/files.zaurus | 7 | ||||
-rw-r--r-- | sys/arch/zaurus/dev/zaurus_scoop.c | 123 | ||||
-rw-r--r-- | sys/arch/zaurus/dev/zaurus_scoopreg.h | 15 | ||||
-rw-r--r-- | sys/arch/zaurus/dev/zaurus_scoopvar.h | 10 | ||||
-rw-r--r-- | sys/arch/zaurus/include/apmvar.h | 1 | ||||
-rw-r--r-- | sys/arch/zaurus/include/conf.h | 14 |
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 */ |