summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2001-01-28 19:49:46 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2001-01-28 19:49:46 +0000
commit26427514c0f9a58640eac6a4ed998aef181d9540 (patch)
tree94c34d46a7e38de3da3147c52eafe507d902847e /sys
parent5f5938b7a6f8939702d75088e5edc87b21530025 (diff)
Adding ADB keyboard/mouse/apple event drivers. From Nbsd with changes to build.
aed configures on newer systems. akbd and ams not tested on system which has a real ADB bus.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/powerpc/mac/aed.c615
-rw-r--r--sys/arch/powerpc/mac/aedvar.h91
-rw-r--r--sys/arch/powerpc/mac/akbd.c578
-rw-r--r--sys/arch/powerpc/mac/akbdmap.h190
-rw-r--r--sys/arch/powerpc/mac/ams.c582
-rw-r--r--sys/arch/powerpc/mac/amsvar.h66
-rw-r--r--sys/arch/powerpc/mac/keyboard.h208
7 files changed, 2330 insertions, 0 deletions
diff --git a/sys/arch/powerpc/mac/aed.c b/sys/arch/powerpc/mac/aed.c
new file mode 100644
index 00000000000..cd6e94c41a4
--- /dev/null
+++ b/sys/arch/powerpc/mac/aed.c
@@ -0,0 +1,615 @@
+/* $NetBSD: aed.c,v 1.5 2000/03/23 06:40:33 thorpej Exp $ */
+
+/*
+ * Copyright (C) 1994 Bradley A. Grantham
+ * 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 Bradley A. Grantham.
+ * 4. 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.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/fcntl.h>
+#include <sys/poll.h>
+#include <sys/select.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/systm.h>
+
+#include <machine/autoconf.h>
+#include <machine/cpu.h>
+
+#include <powerpc/mac/keyboard.h>
+#include <powerpc/mac/adbvar.h>
+#include <powerpc/mac/aedvar.h>
+#include <powerpc/mac/akbdvar.h>
+
+#define spladb splhigh
+
+/*
+ * Function declarations.
+ */
+#ifdef __NetBSD__
+static int aedmatch __P((struct device *, struct cfdata *, void *));
+#endif /* __NetBSD__ */
+#ifdef __OpenBSD__
+static int aedmatch __P((struct device *, void *, void *));
+#endif /* __OpenBSD__ */
+static void aedattach __P((struct device *, struct device *, void *));
+static void aed_emulate_mouse __P((adb_event_t *event));
+static void aed_kbdrpt __P((void *kstate));
+static void aed_dokeyupdown __P((adb_event_t *event));
+static void aed_handoff __P((adb_event_t *event));
+static void aed_enqevent __P((adb_event_t *event));
+
+/*
+ * Global variables.
+ */
+extern int adb_polling; /* Are we polling? (Debugger mode) */
+
+/*
+ * Local variables.
+ */
+static struct aed_softc *aed_sc = NULL;
+static int aed_options = 0; /* | AED_MSEMUL; */
+
+/* Driver definition */
+struct cfdriver aed_cd = {
+ NULL, "aed", DV_DULL
+};
+/* Driver definition */
+struct cfattach aed_ca = {
+ sizeof(struct aed_softc), aedmatch, aedattach
+};
+
+extern struct cfdriver aed_cd;
+
+static int
+aedmatch(parent, cf, aux)
+ struct device *parent;
+#ifdef __NetBSD__
+ struct cfdata *cf;
+#endif /* __NetBSD__ */
+#ifdef __OpenBSD__
+ void *cf;
+#endif /* __OpenBSD__ */
+ void *aux;
+{
+ struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
+ static int aed_matched = 0;
+
+ /* Allow only one instance. */
+ if ((aa_args->origaddr == 0) && (!aed_matched)) {
+ aed_matched = 1;
+ return (1);
+ } else
+ return (0);
+}
+
+static void
+aedattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
+ struct aed_softc *sc = (struct aed_softc *)self;
+
+ timeout_set(&sc->sc_repeat_ch, aed_kbdrpt, aed_sc);
+
+ sc->origaddr = aa_args->origaddr;
+ sc->adbaddr = aa_args->adbaddr;
+ sc->handler_id = aa_args->handler_id;
+
+ sc->sc_evq_tail = 0;
+ sc->sc_evq_len = 0;
+
+ sc->sc_rptdelay = 20;
+ sc->sc_rptinterval = 6;
+ sc->sc_repeating = -1; /* not repeating */
+
+ /* Pull in the options flags. */
+ sc->sc_options = (sc->sc_dev.dv_cfdata->cf_flags | aed_options);
+
+ sc->sc_ioproc = NULL;
+
+ sc->sc_buttons = 0;
+
+ sc->sc_open = 0;
+
+ aed_sc = sc;
+
+ printf("ADB Event device\n");
+
+ return;
+}
+
+/*
+ * Given a keyboard ADB event, record the keycode and call the key
+ * repeat handler, optionally passing the event through the mouse
+ * button emulation handler first. Pass mouse events directly to
+ * the handoff function.
+ */
+void
+aed_input(event)
+ adb_event_t *event;
+{
+ adb_event_t new_event = *event;
+
+ switch (event->def_addr) {
+ case ADBADDR_KBD:
+ if (aed_sc->sc_options & AED_MSEMUL)
+ aed_emulate_mouse(&new_event);
+ else
+ aed_dokeyupdown(&new_event);
+ break;
+ case ADBADDR_MS:
+ new_event.u.m.buttons |= aed_sc->sc_buttons;
+ aed_handoff(&new_event);
+ break;
+ default: /* God only knows. */
+#ifdef DIAGNOSTIC
+ panic("aed: received event from unsupported device!\n");
+#endif
+ break;
+ }
+
+}
+
+/*
+ * Handles mouse button emulation via the keyboard. If the emulation
+ * modifier key is down, left and right arrows will generate 2nd and
+ * 3rd mouse button events while the 1, 2, and 3 keys will generate
+ * the corresponding mouse button event.
+ */
+static void
+aed_emulate_mouse(event)
+ adb_event_t *event;
+{
+ static int emulmodkey_down = 0;
+ adb_event_t new_event;
+
+ if (event->u.k.key == ADBK_KEYDOWN(ADBK_OPTION)) {
+ emulmodkey_down = 1;
+ } else if (event->u.k.key == ADBK_KEYUP(ADBK_OPTION)) {
+ /* key up */
+ emulmodkey_down = 0;
+ if (aed_sc->sc_buttons & 0xfe) {
+ aed_sc->sc_buttons &= 1;
+ new_event.def_addr = ADBADDR_MS;
+ new_event.u.m.buttons = aed_sc->sc_buttons;
+ new_event.u.m.dx = new_event.u.m.dy = 0;
+ microtime(&new_event.timestamp);
+ aed_handoff(&new_event);
+ }
+ } else if (emulmodkey_down) {
+ switch(event->u.k.key) {
+#ifdef ALTXBUTTONS
+ case ADBK_KEYDOWN(ADBK_1):
+ aed_sc->sc_buttons |= 1; /* left down */
+ new_event.def_addr = ADBADDR_MS;
+ new_event.u.m.buttons = aed_sc->sc_buttons;
+ new_event.u.m.dx = new_event.u.m.dy = 0;
+ microtime(&new_event.timestamp);
+ aed_handoff(&new_event);
+ break;
+ case ADBK_KEYUP(ADBK_1):
+ aed_sc->sc_buttons &= ~1; /* left up */
+ new_event.def_addr = ADBADDR_MS;
+ new_event.u.m.buttons = aed_sc->sc_buttons;
+ new_event.u.m.dx = new_event.u.m.dy = 0;
+ microtime(&new_event.timestamp);
+ aed_handoff(&new_event);
+ break;
+#endif
+ case ADBK_KEYDOWN(ADBK_LEFT):
+#ifdef ALTXBUTTONS
+ case ADBK_KEYDOWN(ADBK_2):
+#endif
+ aed_sc->sc_buttons |= 2; /* middle down */
+ new_event.def_addr = ADBADDR_MS;
+ new_event.u.m.buttons = aed_sc->sc_buttons;
+ new_event.u.m.dx = new_event.u.m.dy = 0;
+ microtime(&new_event.timestamp);
+ aed_handoff(&new_event);
+ break;
+ case ADBK_KEYUP(ADBK_LEFT):
+#ifdef ALTXBUTTONS
+ case ADBK_KEYUP(ADBK_2):
+#endif
+ aed_sc->sc_buttons &= ~2; /* middle up */
+ new_event.def_addr = ADBADDR_MS;
+ new_event.u.m.buttons = aed_sc->sc_buttons;
+ new_event.u.m.dx = new_event.u.m.dy = 0;
+ microtime(&new_event.timestamp);
+ aed_handoff(&new_event);
+ break;
+ case ADBK_KEYDOWN(ADBK_RIGHT):
+#ifdef ALTXBUTTONS
+ case ADBK_KEYDOWN(ADBK_3):
+#endif
+ aed_sc->sc_buttons |= 4; /* right down */
+ new_event.def_addr = ADBADDR_MS;
+ new_event.u.m.buttons = aed_sc->sc_buttons;
+ new_event.u.m.dx = new_event.u.m.dy = 0;
+ microtime(&new_event.timestamp);
+ aed_handoff(&new_event);
+ break;
+ case ADBK_KEYUP(ADBK_RIGHT):
+#ifdef ALTXBUTTONS
+ case ADBK_KEYUP(ADBK_3):
+#endif
+ aed_sc->sc_buttons &= ~4; /* right up */
+ new_event.def_addr = ADBADDR_MS;
+ new_event.u.m.buttons = aed_sc->sc_buttons;
+ new_event.u.m.dx = new_event.u.m.dy = 0;
+ microtime(&new_event.timestamp);
+ aed_handoff(&new_event);
+ break;
+ case ADBK_KEYUP(ADBK_SHIFT):
+ case ADBK_KEYDOWN(ADBK_SHIFT):
+ case ADBK_KEYUP(ADBK_CONTROL):
+ case ADBK_KEYDOWN(ADBK_CONTROL):
+ case ADBK_KEYUP(ADBK_FLOWER):
+ case ADBK_KEYDOWN(ADBK_FLOWER):
+ /* ctrl, shift, cmd */
+ aed_dokeyupdown(event);
+ break;
+ default:
+ if (event->u.k.key & 0x80)
+ /* ignore keyup */
+ break;
+
+ /* key down */
+ new_event = *event;
+
+ /* send option-down */
+ new_event.u.k.key = ADBK_KEYDOWN(ADBK_OPTION);
+ new_event.bytes[0] = new_event.u.k.key;
+ microtime(&new_event.timestamp);
+ aed_dokeyupdown(&new_event);
+
+ /* send key-down */
+ new_event.u.k.key = event->bytes[0];
+ new_event.bytes[0] = new_event.u.k.key;
+ microtime(&new_event.timestamp);
+ aed_dokeyupdown(&new_event);
+
+ /* send key-up */
+ new_event.u.k.key =
+ ADBK_KEYUP(ADBK_KEYVAL(event->bytes[0]));
+ microtime(&new_event.timestamp);
+ new_event.bytes[0] = new_event.u.k.key;
+ aed_dokeyupdown(&new_event);
+
+ /* send option-up */
+ new_event.u.k.key = ADBK_KEYUP(ADBK_OPTION);
+ new_event.bytes[0] = new_event.u.k.key;
+ microtime(&new_event.timestamp);
+ aed_dokeyupdown(&new_event);
+ break;
+ }
+ } else {
+ aed_dokeyupdown(event);
+ }
+}
+
+/*
+ * Keyboard autorepeat timeout function. Sends key up/down events
+ * for the repeating key and schedules the next call at sc_rptinterval
+ * ticks in the future.
+ */
+static void
+aed_kbdrpt(kstate)
+ void *kstate;
+{
+ struct aed_softc *aed_sc = (struct aed_softc *)kstate;
+
+ aed_sc->sc_rptevent.bytes[0] |= 0x80;
+ microtime(&aed_sc->sc_rptevent.timestamp);
+ aed_handoff(&aed_sc->sc_rptevent); /* do key up */
+
+ aed_sc->sc_rptevent.bytes[0] &= 0x7f;
+ microtime(&aed_sc->sc_rptevent.timestamp);
+ aed_handoff(&aed_sc->sc_rptevent); /* do key down */
+
+ if (aed_sc->sc_repeating == aed_sc->sc_rptevent.u.k.key) {
+ timeout_add(&aed_sc->sc_repeat_ch, aed_sc->sc_rptinterval);
+ }
+}
+
+
+/*
+ * Cancels the currently repeating key event if there is one, schedules
+ * a new repeating key event if needed, and hands the event off to the
+ * appropriate subsystem.
+ */
+static void
+aed_dokeyupdown(event)
+ adb_event_t *event;
+{
+ int kbd_key;
+
+ kbd_key = ADBK_KEYVAL(event->u.k.key);
+ if (ADBK_PRESS(event->u.k.key) && keyboard[kbd_key][0] != 0) {
+ /* ignore shift & control */
+ if (aed_sc->sc_repeating != -1) {
+ timeout_del(&aed_sc->sc_repeat_ch);
+ }
+ aed_sc->sc_rptevent = *event;
+ aed_sc->sc_repeating = kbd_key;
+ timeout_add(&aed_sc->sc_repeat_ch, aed_sc->sc_rptdelay);
+ } else {
+ if (aed_sc->sc_repeating != -1) {
+ aed_sc->sc_repeating = -1;
+ timeout_del(&aed_sc->sc_repeat_ch);
+ }
+ aed_sc->sc_rptevent = *event;
+ }
+ aed_handoff(event);
+}
+
+/*
+ * Place the event in the event queue if a requesting device is open
+ * and we are not polling.
+ */
+static void
+aed_handoff(event)
+ adb_event_t *event;
+{
+ if (aed_sc->sc_open && !adb_polling)
+ aed_enqevent(event);
+}
+
+/*
+ * Place the event in the event queue and wakeup any waiting processes.
+ */
+static void
+aed_enqevent(event)
+ adb_event_t *event;
+{
+ int s;
+
+ s = spladb();
+
+#ifdef DIAGNOSTIC
+ if (aed_sc->sc_evq_tail < 0 || aed_sc->sc_evq_tail >= AED_MAX_EVENTS)
+ panic("adb: event queue tail is out of bounds");
+
+ if (aed_sc->sc_evq_len < 0 || aed_sc->sc_evq_len > AED_MAX_EVENTS)
+ panic("adb: event queue len is out of bounds");
+#endif
+
+ if (aed_sc->sc_evq_len == AED_MAX_EVENTS) {
+ splx(s);
+ return; /* Oh, well... */
+ }
+ aed_sc->sc_evq[(aed_sc->sc_evq_len + aed_sc->sc_evq_tail) %
+ AED_MAX_EVENTS] = *event;
+ aed_sc->sc_evq_len++;
+
+ selwakeup(&aed_sc->sc_selinfo);
+ if (aed_sc->sc_ioproc)
+ psignal(aed_sc->sc_ioproc, SIGIO);
+
+ splx(s);
+}
+
+int
+aedopen(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ int unit;
+ int error = 0;
+ int s;
+
+ unit = minor(dev);
+
+ if (unit != 0)
+ return (ENXIO);
+
+ s = spladb();
+ if (aed_sc->sc_open) {
+ splx(s);
+ return (EBUSY);
+ }
+ aed_sc->sc_evq_tail = 0;
+ aed_sc->sc_evq_len = 0;
+ aed_sc->sc_open = 1;
+ aed_sc->sc_ioproc = p;
+ splx(s);
+
+ return (error);
+}
+
+
+int
+aedclose(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ int s = spladb();
+
+ aed_sc->sc_open = 0;
+ aed_sc->sc_ioproc = NULL;
+ splx(s);
+
+ return (0);
+}
+
+
+int
+aedread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ int s, error;
+ int willfit;
+ int total;
+ int firstmove;
+ int moremove;
+
+ if (uio->uio_resid < sizeof(adb_event_t))
+ return (EMSGSIZE); /* close enough. */
+
+ s = spladb();
+ if (aed_sc->sc_evq_len == 0) {
+ splx(s);
+ return (0);
+ }
+ willfit = howmany(uio->uio_resid, sizeof(adb_event_t));
+ total = (aed_sc->sc_evq_len < willfit) ? aed_sc->sc_evq_len : willfit;
+
+ firstmove = (aed_sc->sc_evq_tail + total > AED_MAX_EVENTS)
+ ? (AED_MAX_EVENTS - aed_sc->sc_evq_tail) : total;
+
+ error = uiomove((caddr_t) & aed_sc->sc_evq[aed_sc->sc_evq_tail],
+ firstmove * sizeof(adb_event_t), uio);
+ if (error) {
+ splx(s);
+ return (error);
+ }
+ moremove = total - firstmove;
+
+ if (moremove > 0) {
+ error = uiomove((caddr_t) & aed_sc->sc_evq[0],
+ moremove * sizeof(adb_event_t), uio);
+ if (error) {
+ splx(s);
+ return (error);
+ }
+ }
+ aed_sc->sc_evq_tail = (aed_sc->sc_evq_tail + total) % AED_MAX_EVENTS;
+ aed_sc->sc_evq_len -= total;
+ splx(s);
+ return (0);
+}
+
+
+int
+aedwrite(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ return 0;
+}
+
+
+int
+aedioctl(dev, cmd, data, flag, p)
+ dev_t dev;
+ int cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ switch (cmd) {
+ case ADBIOCDEVSINFO: {
+ adb_devinfo_t *di;
+ ADBDataBlock adbdata;
+ int totaldevs;
+ int adbaddr;
+ int i;
+
+ di = (void *)data;
+
+ /* Initialize to no devices */
+ for (i = 0; i < 16; i++)
+ di->dev[i].addr = -1;
+
+ totaldevs = CountADBs();
+ for (i = 1; i <= totaldevs; i++) {
+ adbaddr = GetIndADB(&adbdata, i);
+ di->dev[adbaddr].addr = adbaddr;
+ di->dev[adbaddr].default_addr = (int)(adbdata.origADBAddr);
+ di->dev[adbaddr].handler_id = (int)(adbdata.devType);
+ }
+
+ /* Must call ADB Manager to get devices now */
+ break;
+ }
+
+ case ADBIOCGETREPEAT:{
+ adb_rptinfo_t *ri;
+
+ ri = (void *)data;
+ ri->delay_ticks = aed_sc->sc_rptdelay;
+ ri->interval_ticks = aed_sc->sc_rptinterval;
+ break;
+ }
+
+ case ADBIOCSETREPEAT:{
+ adb_rptinfo_t *ri;
+
+ ri = (void *) data;
+ aed_sc->sc_rptdelay = ri->delay_ticks;
+ aed_sc->sc_rptinterval = ri->interval_ticks;
+ break;
+ }
+
+ case ADBIOCRESET:
+ /* Do nothing for now */
+ break;
+
+ case ADBIOCLISTENCMD:{
+ adb_listencmd_t *lc;
+
+ lc = (void *)data;
+ }
+
+ default:
+ return (EINVAL);
+ }
+ return (0);
+}
+
+
+int
+aedpoll(dev, events, p)
+ dev_t dev;
+ int events;
+ struct proc *p;
+{
+ int s, revents;
+
+ revents = events & (POLLOUT | POLLWRNORM);
+
+ if ((events & (POLLIN | POLLRDNORM)) == 0)
+ return (revents);
+
+ s = spladb();
+ if (aed_sc->sc_evq_len > 0)
+ revents |= events & (POLLIN | POLLRDNORM);
+ else
+ selrecord(p, &aed_sc->sc_selinfo);
+ splx(s);
+
+ return (revents);
+}
diff --git a/sys/arch/powerpc/mac/aedvar.h b/sys/arch/powerpc/mac/aedvar.h
new file mode 100644
index 00000000000..ab3d7a569d2
--- /dev/null
+++ b/sys/arch/powerpc/mac/aedvar.h
@@ -0,0 +1,91 @@
+/* $NetBSD: aedvar.h,v 1.2 2000/03/23 06:40:33 thorpej Exp $ */
+
+/*
+ * Copyright (C) 1994 Bradley A. Grantham
+ * 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 Bradley A. Grantham.
+ * 4. 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.
+ */
+
+#ifdef __NetBSD__
+#include <sys/callout.h>
+#endif /* __NetBSD__ */
+#ifdef __OpenBSD__
+#include <sys/timeout.h>
+#endif /* __OpenBSD__ */
+#include <machine/adbsys.h>
+
+/* Event queue definitions */
+#ifndef AED_MAX_EVENTS
+#define AED_MAX_EVENTS 200 /* Maximum events to be kept in queue */
+ /* maybe should be higher for slower macs? */
+#endif /* AED_MAX_EVENTS */
+
+struct aed_softc {
+ struct device sc_dev;
+
+#ifdef __NetBSD__
+ struct callout sc_repeat_ch;
+#endif /* __NetBSD__ */
+#ifdef __OpenBSD__
+ struct timeout sc_repeat_ch;
+#endif /* __OpenBSD__ */
+
+ /* ADB info */
+ u_char origaddr; /* ADB device type (ADBADDR_AED) */
+ u_char adbaddr; /* current ADB address */
+ u_char handler_id; /* type of device */
+
+ /* ADB event queue */
+ adb_event_t sc_evq[AED_MAX_EVENTS]; /* the queue */
+ int sc_evq_tail; /* event queue tail pointer */
+ int sc_evq_len; /* event queue length */
+
+ /* Keyboard repeat state */
+ int sc_rptdelay; /* ticks before auto-repeat */
+ int sc_rptinterval; /* ticks between auto-repeat */
+ int sc_repeating; /* key that is auto-repeating */
+ adb_event_t sc_rptevent; /* event to auto-repeat */
+
+ int sc_buttons; /* mouse button state */
+
+ struct selinfo sc_selinfo; /* select() info */
+ struct proc * sc_ioproc; /* process to wakeup */
+
+ int sc_open; /* Are we queuing events? */
+ int sc_options; /* config options */
+};
+
+/* Options */
+#define AED_MSEMUL 0x1 /* emulate mouse buttons */
+
+void aed_input __P((adb_event_t *event));
+int aedopen __P((dev_t dev, int flag, int mode, struct proc *p));
+int aedclose __P((dev_t dev, int flag, int mode, struct proc *p));
+int aedread __P((dev_t dev, struct uio *uio, int flag));
+int aedwrite __P((dev_t dev, struct uio *uio, int flag));
+int aedioctl __P((dev_t , int , caddr_t , int , struct proc *));
+int aedpoll __P((dev_t dev, int events, struct proc *p));
diff --git a/sys/arch/powerpc/mac/akbd.c b/sys/arch/powerpc/mac/akbd.c
new file mode 100644
index 00000000000..fa04abc9aff
--- /dev/null
+++ b/sys/arch/powerpc/mac/akbd.c
@@ -0,0 +1,578 @@
+/* $OpenBSD: akbd.c,v 1.1 2001/01/28 19:49:45 drahn Exp $ */
+/* $NetBSD: akbd.c,v 1.10 2000/09/01 16:00:38 tsubai Exp $ */
+
+/*
+ * Copyright (C) 1998 Colin Wood
+ * 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 Colin Wood.
+ * 4. 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.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/fcntl.h>
+#include <sys/poll.h>
+#include <sys/select.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/systm.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wskbdvar.h>
+#include <dev/wscons/wsksymdef.h>
+#include <dev/wscons/wsksymvar.h>
+
+#include <machine/autoconf.h>
+#define KEYBOARD_ARRAY
+
+#include <powerpc/mac/keyboard.h>
+#include <powerpc/mac/adbvar.h>
+#include <powerpc/mac/aedvar.h>
+#include <powerpc/mac/akbdmap.h>
+#include <powerpc/mac/akbdvar.h>
+#include <powerpc/mac/amsvar.h>
+
+#include "aed.h"
+
+/*
+ * Function declarations.
+ */
+static int akbdmatch __P((struct device *, void *, void *));
+static void akbdattach __P((struct device *, struct device *, void *));
+void kbd_adbcomplete __P((caddr_t buffer, caddr_t data_area, int adb_command));
+static void kbd_processevent __P((adb_event_t *event, struct akbd_softc *));
+#ifdef notyet
+static u_char getleds __P((int));
+static int setleds __P((struct akbd_softc *, u_char));
+static void blinkleds __P((struct akbd_softc *));
+#endif
+
+/*
+ * Local variables.
+ */
+static volatile int kbd_done; /* Did ADBOp() complete? */
+
+/* Driver definition. */
+struct cfdriver akbd_cd = {
+ NULL, "akbd", DV_DULL
+};
+
+/* Driver definition. */
+struct cfattach akbd_ca = {
+ sizeof(struct akbd_softc), akbdmatch, akbdattach
+};
+
+extern struct cfdriver akbd_cd;
+
+int akbd_enable __P((void *, int));
+void akbd_set_leds __P((void *, int));
+int akbd_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
+
+struct wskbd_accessops akbd_accessops = {
+ akbd_enable,
+ akbd_set_leds,
+ akbd_ioctl,
+};
+
+void akbd_cngetc __P((void *, u_int *, int *));
+void akbd_cnpollc __P((void *, int));
+
+struct wskbd_consops akbd_consops = {
+ akbd_cngetc,
+ akbd_cnpollc,
+};
+
+struct wskbd_mapdata akbd_keymapdata = {
+ akbd_keydesctab,
+#ifdef AKBD_LAYOUT
+ AKBD_LAYOUT,
+#else
+ KB_US,
+#endif
+};
+
+static int akbd_is_console;
+
+static int
+akbdmatch(parent, cf, aux)
+ struct device *parent;
+ void *cf;
+ void *aux;
+{
+ struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
+
+ if (aa_args->origaddr == ADBADDR_KBD)
+ return 1;
+ else
+ return 0;
+}
+
+static void
+akbdattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ ADBSetInfoBlock adbinfo;
+ struct akbd_softc *sc = (struct akbd_softc *)self;
+ struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
+ int count, error;
+ short cmd;
+ u_char buffer[9];
+ struct wskbddev_attach_args a;
+
+ sc->origaddr = aa_args->origaddr;
+ sc->adbaddr = aa_args->adbaddr;
+ sc->handler_id = aa_args->handler_id;
+
+ sc->sc_leds = (u_int8_t)0x00; /* initially off */
+
+ adbinfo.siServiceRtPtr = (Ptr)kbd_adbcomplete;
+ adbinfo.siDataAreaAddr = (caddr_t)sc;
+
+ switch (sc->handler_id) {
+ case ADB_STDKBD:
+ printf("standard keyboard\n");
+ break;
+ case ADB_ISOKBD:
+ printf("standard keyboard (ISO layout)\n");
+ break;
+ case ADB_EXTKBD:
+ kbd_done = 0;
+ cmd = (((sc->adbaddr << 4) & 0xf0) | 0x0d ); /* talk R1 */
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ (Ptr)&kbd_done, cmd);
+
+ /* Wait until done, but no more than 2 secs */
+ count = 40000;
+ while (!kbd_done && count-- > 0)
+ delay(50);
+
+ /* Ignore Logitech MouseMan/Trackman pseudo keyboard */
+ if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x20) {
+ printf("Mouseman (non-EMP) pseudo keyboard\n");
+ adbinfo.siServiceRtPtr = (Ptr)0;
+ adbinfo.siDataAreaAddr = (Ptr)0;
+ } else if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x21) {
+ printf("Trackman (non-EMP) pseudo keyboard\n");
+ adbinfo.siServiceRtPtr = (Ptr)0;
+ adbinfo.siDataAreaAddr = (Ptr)0;
+ } else {
+ printf("extended keyboard\n");
+#ifdef notyet
+ blinkleds(sc);
+#endif
+ }
+ break;
+ case ADB_EXTISOKBD:
+ printf("extended keyboard (ISO layout)\n");
+#ifdef notyet
+ blinkleds(sc);
+#endif
+ break;
+ case ADB_KBDII:
+ printf("keyboard II\n");
+ break;
+ case ADB_ISOKBDII:
+ printf("keyboard II (ISO layout)\n");
+ break;
+ case ADB_PBKBD:
+ printf("PowerBook keyboard\n");
+ break;
+ case ADB_PBISOKBD:
+ printf("PowerBook keyboard (ISO layout)\n");
+ break;
+ case ADB_ADJKPD:
+ printf("adjustable keypad\n");
+ break;
+ case ADB_ADJKBD:
+ printf("adjustable keyboard\n");
+ break;
+ case ADB_ADJISOKBD:
+ printf("adjustable keyboard (ISO layout)\n");
+ break;
+ case ADB_ADJJAPKBD:
+ printf("adjustable keyboard (Japanese layout)\n");
+ break;
+ case ADB_PBEXTISOKBD:
+ printf("PowerBook extended keyboard (ISO layout)\n");
+ break;
+ case ADB_PBEXTJAPKBD:
+ printf("PowerBook extended keyboard (Japanese layout)\n");
+ break;
+ case ADB_JPKBDII:
+ printf("keyboard II (Japanese layout)\n");
+ break;
+ case ADB_PBEXTKBD:
+ printf("PowerBook extended keyboard\n");
+ break;
+ case ADB_DESIGNKBD:
+ printf("extended keyboard\n");
+#ifdef notyet
+ blinkleds(sc);
+#endif
+ break;
+#ifdef ADB_PBJPKBD
+ case ADB_PBJPKBD:
+ printf("PowerBook keyboard (Japanese layout)\n");
+ break;
+#endif /* ADB_PBJPKBD */
+#ifdef ADB_PBG3JPKBD
+ case ADB_PBG3JPKBD:
+ printf("PowerBook G3 keyboard (Japanese layout)\n");
+ break;
+#endif /* ADB_PBG3JPKBD */
+ default:
+ printf("mapped device (%d)\n", sc->handler_id);
+ break;
+ }
+ error = SetADBInfo(&adbinfo, sc->adbaddr);
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf("kbd: returned %d from SetADBInfo\n", error);
+#endif
+
+ a.console = akbd_is_console;
+ a.keymap = &akbd_keymapdata;
+ a.accessops = &akbd_accessops;
+ a.accesscookie = sc;
+
+ sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
+}
+
+
+/*
+ * Handle putting the keyboard data received from the ADB into
+ * an ADB event record.
+ */
+void
+kbd_adbcomplete(buffer, data_area, adb_command)
+ caddr_t buffer;
+ caddr_t data_area;
+ int adb_command;
+{
+ adb_event_t event;
+ struct akbd_softc *ksc;
+ int adbaddr;
+#ifdef ADB_DEBUG
+ int i;
+
+ if (adb_debug)
+ printf("adb: transaction completion\n");
+#endif
+
+ adbaddr = (adb_command & 0xf0) >> 4;
+ ksc = (struct akbd_softc *)data_area;
+
+ event.addr = adbaddr;
+ event.hand_id = ksc->handler_id;
+ event.def_addr = ksc->origaddr;
+ event.byte_count = buffer[0];
+ memcpy(event.bytes, buffer + 1, event.byte_count);
+
+#ifdef ADB_DEBUG
+ if (adb_debug) {
+ printf("kbd: from %d at %d (org %d) %d:", event.addr,
+ event.hand_id, event.def_addr, buffer[0]);
+ for (i = 1; i <= buffer[0]; i++)
+ printf(" %x", buffer[i]);
+ printf("\n");
+ }
+#endif
+
+ microtime(&event.timestamp);
+
+ kbd_processevent(&event, ksc);
+}
+
+/*
+ * Given a keyboard ADB event, record the keycodes and call the key
+ * repeat handler, optionally passing the event through the mouse
+ * button emulation handler first.
+ */
+static void
+kbd_processevent(event, ksc)
+ adb_event_t *event;
+ struct akbd_softc *ksc;
+{
+ adb_event_t new_event;
+
+ new_event = *event;
+ new_event.u.k.key = event->bytes[0];
+ new_event.bytes[1] = 0xff;
+ kbd_intr(&new_event);
+#if NAED > 0
+ aed_input(&new_event);
+#endif
+ if (event->bytes[1] != 0xff) {
+ new_event.u.k.key = event->bytes[1];
+ new_event.bytes[0] = event->bytes[1];
+ new_event.bytes[1] = 0xff;
+ kbd_intr(&new_event);
+#if NAED > 0
+ aed_input(&new_event);
+#endif
+ }
+
+}
+
+#ifdef notyet
+/*
+ * Get the actual hardware LED state and convert it to softc format.
+ */
+static u_char
+getleds(addr)
+ int addr;
+{
+ short cmd;
+ u_char buffer[9], leds;
+
+ leds = 0x00; /* all off */
+ buffer[0] = 0;
+ kbd_done = 0;
+
+ /* talk R2 */
+ cmd = ((addr & 0xf) << 4) | 0x0c | 0x02;
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete, (Ptr)&kbd_done, cmd);
+ while (!kbd_done)
+ /* busy-wait until done */ ;
+
+ if (buffer[0] > 0)
+ leds = ~(buffer[2]) & 0x07;
+
+ return (leds);
+}
+
+/*
+ * Set the keyboard LED's.
+ *
+ * Automatically translates from ioctl/softc format to the
+ * actual keyboard register format
+ */
+static int
+setleds(ksc, leds)
+ struct akbd_softc *ksc;
+ u_char leds;
+{
+ int addr;
+ short cmd;
+ u_char buffer[9];
+
+ if ((leds & 0x07) == (ksc->sc_leds & 0x07))
+ return (0);
+
+ addr = ksc->adbaddr;
+ buffer[0] = 0;
+ kbd_done = 0;
+
+ /* talk R2 */
+ cmd = ((addr & 0xf) << 4) | 0x0c | 0x02;
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete, (Ptr)&kbd_done, cmd);
+ while (!kbd_done)
+ /* busy-wait until done */ ;
+
+ if (buffer[0] == 0)
+ return (EIO);
+
+ leds = ~leds & 0x07;
+ buffer[2] &= 0xf8;
+ buffer[2] |= leds;
+
+ /* listen R2 */
+ cmd = ((addr & 0xf) << 4) | 0x08 | 0x02;
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete, (Ptr)&kbd_done, cmd);
+ while (!kbd_done)
+ /* busy-wait until done */ ;
+
+ /* talk R2 */
+ cmd = ((addr & 0xf) << 4) | 0x0c | 0x02;
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete, (Ptr)&kbd_done, cmd);
+ while (!kbd_done)
+ /* busy-wait until done */ ;
+
+ if (buffer[0] == 0)
+ return (EIO);
+
+ ksc->sc_leds = ~((u_int8_t)buffer[2]) & 0x07;
+
+ if ((buffer[2] & 0xf8) != leds)
+ return (EIO);
+ else
+ return (0);
+}
+
+/*
+ * Toggle all of the LED's on and off, just for show.
+ */
+static void
+blinkleds(ksc)
+ struct akbd_softc *ksc;
+{
+ int addr, i;
+ u_char blinkleds, origleds;
+
+ addr = ksc->adbaddr;
+ origleds = getleds(addr);
+ blinkleds = LED_NUMLOCK | LED_CAPSLOCK | LED_SCROLL_LOCK;
+
+ (void)setleds(ksc, blinkleds);
+
+ for (i = 0; i < 10000; i++)
+ delay(50);
+
+ /* make sure that we restore the LED settings */
+ i = 10;
+ do {
+ (void)setleds(ksc, (u_char)0x00);
+ } while (setleds(ksc, (u_char)0x00) && (i-- > 0));
+
+ return;
+}
+#endif
+
+int
+akbd_enable(v, on)
+ void *v;
+ int on;
+{
+ return 0;
+}
+
+void
+akbd_set_leds(v, on)
+ void *v;
+ int on;
+{
+}
+
+int
+akbd_ioctl(v, cmd, data, flag, p)
+ void *v;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ switch (cmd) {
+
+ case WSKBDIO_GTYPE:
+ *(int *)data = 0; /* XXX */
+ return 0;
+ case WSKBDIO_SETLEDS:
+ return 0;
+ case WSKBDIO_GETLEDS:
+ *(int *)data = 0;
+ return 0;
+ }
+ /* kbdioctl(...); */
+
+ return -1;
+}
+
+static int polledkey;
+extern int adb_polling;
+
+int
+kbd_intr(event)
+ adb_event_t *event;
+{
+ int key, press, val;
+ int type;
+
+ struct akbd_softc *sc = akbd_cd.cd_devs[0];
+
+ key = event->u.k.key;
+ press = ADBK_PRESS(key);
+ val = ADBK_KEYVAL(key);
+
+ type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
+
+ switch (key) {
+ case 185: /* Caps Lock released */
+ type = WSCONS_EVENT_KEY_DOWN;
+ wskbd_input(sc->sc_wskbddev, type, val);
+ type = WSCONS_EVENT_KEY_UP;
+ break;
+ case 245:
+ pm_eject_pcmcia(0);
+ break;
+ case 244:
+ pm_eject_pcmcia(1);
+ break;
+ }
+
+ if (adb_polling)
+ polledkey = key;
+ else
+ wskbd_input(sc->sc_wskbddev, type, val);
+
+ return 0;
+}
+
+int
+akbd_cnattach()
+{
+
+ akbd_is_console = 1;
+ wskbd_cnattach(&akbd_consops, NULL, &akbd_keymapdata);
+ return 0;
+}
+
+void
+akbd_cngetc(v, type, data)
+ void *v;
+ u_int *type;
+ int *data;
+{
+ int key, press, val;
+ int s;
+
+ s = splhigh();
+
+ polledkey = -1;
+ adb_polling = 1;
+
+ while (polledkey == -1) {
+ adb_intr();
+ DELAY(10000); /* XXX */
+ }
+
+ adb_polling = 0;
+ splx(s);
+
+ key = polledkey;
+ press = ADBK_PRESS(key);
+ val = ADBK_KEYVAL(key);
+
+ *data = val;
+ *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
+}
+
+void
+akbd_cnpollc(v, on)
+ void *v;
+ int on;
+{
+}
diff --git a/sys/arch/powerpc/mac/akbdmap.h b/sys/arch/powerpc/mac/akbdmap.h
new file mode 100644
index 00000000000..656c64f7433
--- /dev/null
+++ b/sys/arch/powerpc/mac/akbdmap.h
@@ -0,0 +1,190 @@
+/* $NetBSD: akbdmap.h,v 1.3 2000/09/01 16:00:39 tsubai Exp $ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Juergen Hannken-Illjes.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/* XXX This list is incomplete. */
+
+#define KC(n) KS_KEYCODE(n)
+
+static const keysym_t akbd_keydesc_us[] = {
+/* pos command normal shifted */
+ KC(0), KS_a,
+ KC(1), KS_s,
+ KC(2), KS_d,
+ KC(3), KS_f,
+ KC(4), KS_h,
+ KC(5), KS_g,
+ KC(6), KS_z,
+ KC(7), KS_x,
+ KC(8), KS_c,
+ KC(9), KS_v,
+
+ KC(11), KS_b,
+ KC(12), KS_q,
+ KC(13), KS_w,
+ KC(14), KS_e,
+ KC(15), KS_r,
+ KC(16), KS_y,
+ KC(17), KS_t,
+ KC(18), KS_1, KS_exclam,
+ KC(19), KS_2, KS_at,
+ KC(20), KS_3, KS_numbersign,
+ KC(21), KS_4, KS_dollar,
+ KC(22), KS_6, KS_asciicircum,
+ KC(23), KS_5, KS_percent,
+ KC(24), KS_equal, KS_plus,
+ KC(25), KS_9, KS_parenleft,
+ KC(26), KS_7, KS_ampersand,
+ KC(27), KS_minus, KS_underscore,
+ KC(28), KS_8, KS_asterisk,
+ KC(29), KS_0, KS_parenright,
+ KC(30), KS_bracketright, KS_braceright,
+ KC(31), KS_o,
+ KC(32), KS_u,
+ KC(33), KS_bracketleft, KS_braceleft,
+ KC(34), KS_i,
+ KC(35), KS_p,
+ KC(36), KS_Return,
+ KC(37), KS_l,
+ KC(38), KS_j,
+ KC(39), KS_apostrophe, KS_quotedbl,
+ KC(40), KS_k,
+ KC(41), KS_semicolon, KS_colon,
+ KC(42), KS_backslash, KS_bar,
+ KC(43), KS_comma, KS_less,
+ KC(44), KS_slash, KS_question,
+ KC(45), KS_n,
+ KC(46), KS_m,
+ KC(47), KS_period, KS_greater,
+ KC(48), KS_Tab,
+ KC(49), KS_space,
+ KC(50), KS_grave, KS_asciitilde,
+ KC(51), KS_Delete,
+
+ KC(53), KS_Escape,
+ KC(54), KS_Control_L,
+ KC(55), KS_Cmd, /* Command */
+ KC(56), KS_Shift_L,
+ KC(57), KS_Caps_Lock,
+ KC(58), KS_Cmd1, /* Option */
+ KC(59), KS_Left,
+ KC(60), KS_Right,
+ KC(61), KS_Down,
+ KC(62), KS_Up,
+
+ KC(65), KS_KP_Decimal,
+ KC(67), KS_KP_Multiply,
+ KC(69), KS_KP_Add,
+ KC(71), KS_Clear,
+ KC(75), KS_KP_Divide,
+ KC(76), KS_KP_Enter,
+ KC(78), KS_KP_Subtract,
+
+ KC(81), KS_KP_Equal,
+ KC(82), KS_KP_0,
+ KC(83), KS_KP_1,
+ KC(84), KS_KP_2,
+ KC(85), KS_KP_3,
+ KC(86), KS_KP_4,
+ KC(87), KS_KP_5,
+ KC(88), KS_KP_6,
+ KC(89), KS_KP_7,
+
+ KC(91), KS_KP_8,
+ KC(92), KS_KP_9,
+
+ KC(95), KS_comma, /* XXX KS_KP_comma */
+
+ KC(106), KS_KP_Enter,
+
+ KC(127), KS_Cmd_Debugger,
+};
+
+static const keysym_t akbd_keydesc_fr[] = {
+/* pos normal shifted altgr shift-altgr */
+ KC(0), KS_q,
+ KC(6), KS_w,
+ KC(10), KS_at, KS_numbersign,
+ KC(12), KS_a,
+ KC(13), KS_z,
+ KC(18), KS_ampersand, KS_1,
+ KC(19), KS_eacute, KS_2, KS_asciitilde,
+ KC(20), KS_quotedbl, KS_3, KS_numbersign,
+ KC(21), KS_apostrophe, KS_4, KS_braceleft,
+ KC(22), KS_section, KS_6, KS_bar,
+ KC(23), KS_parenleft, KS_5, KS_bracketleft, KS_braceleft,
+ KC(24), KS_minus, KS_underscore, KS_braceright,
+ KC(25), KS_ccedilla, KS_9, KS_asciicircum,
+ KC(26), KS_egrave, KS_7, KS_grave,
+ KC(27), KS_parenright, KS_degree, KS_bracketright, KS_braceright,
+ KC(28), KS_exclam, KS_8, KS_bar,
+ KC(29), KS_agrave, KS_0, KS_at,
+ KC(30), KS_dollar, KS_asterisk,
+ KC(33), KS_dead_circumflex, KS_dead_diaeresis,
+ KC(39), KS_mu, KS_percent,
+ KC(40), KS_k,
+ KC(41), KS_m,
+ KC(42), KS_grave, KS_sterling,
+ KC(43), KS_semicolon, KS_period,
+ KC(44), KS_equal, KS_plus,
+ KC(46), KS_comma, KS_question,
+ KC(47), KS_colon, KS_slash, KS_backslash,
+ KC(50), KS_less, KS_greater,
+ KC(52), KS_Alt_R,
+ KC(55), KS_Meta_L, /* Command */
+ KC(58), KS_Alt_R, /* Option */
+};
+
+#if 0
+static const keysym_t akbd_keydesc_jp[] = {
+/* pos command normal shifted */
+ KC(42), KS_grave, KS_asciitilde,
+ KC(93), KS_backslash, KS_bar,
+};
+#endif
+
+#define KBD_MAP(name, base, map) \
+ { name, base, sizeof(map)/sizeof(keysym_t), map }
+
+static const struct wscons_keydesc akbd_keydesctab[] = {
+ KBD_MAP(KB_US, 0, akbd_keydesc_us),
+ KBD_MAP(KB_FR, KB_US, akbd_keydesc_fr),
+ {0, 0, 0, 0}
+};
+
+#undef KBD_MAP
+#undef KC
diff --git a/sys/arch/powerpc/mac/ams.c b/sys/arch/powerpc/mac/ams.c
new file mode 100644
index 00000000000..e8033ea4152
--- /dev/null
+++ b/sys/arch/powerpc/mac/ams.c
@@ -0,0 +1,582 @@
+/* $NetBSD: ams.c,v 1.8 2000/01/08 02:57:25 takemura Exp $ */
+
+/*
+ * Copyright (C) 1998 Colin Wood
+ * 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 Colin Wood.
+ * 4. 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.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/fcntl.h>
+#include <sys/poll.h>
+#include <sys/select.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/systm.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsmousevar.h>
+
+#include <machine/autoconf.h>
+
+#include <powerpc/mac/adbvar.h>
+#include <powerpc/mac/aedvar.h>
+#include <powerpc/mac/amsvar.h>
+
+#include "aed.h"
+
+/*
+ * Function declarations.
+ */
+static int amsmatch __P((struct device *, void *, void *));
+static void amsattach __P((struct device *, struct device *, void *));
+static void ems_init __P((struct ams_softc *));
+static void ms_processevent __P((adb_event_t *event, struct ams_softc *));
+
+/*
+ * Global variables.
+ */
+extern int kbd_polling; /* Are we polling (Debugger mode)? from kbd.c */
+
+/*
+ * Local variables.
+ */
+static volatile int extdms_done; /* Did ADBOp() complete? */
+
+
+/* Driver definition. */
+struct cfdriver ams_cd = {
+ NULL, "ams", DV_DULL
+};
+/* Driver definition. */
+struct cfattach ams_ca = {
+ sizeof(struct ams_softc), amsmatch, amsattach
+};
+
+extern struct cfdriver ms_cd;
+
+int ams_enable __P((void *));
+int ams_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
+void ams_disable __P((void *));
+
+const struct wsmouse_accessops ams_accessops = {
+ ams_enable,
+ ams_ioctl,
+ ams_disable,
+};
+
+static int
+amsmatch(parent, cf, aux)
+ struct device *parent;
+ void *cf;
+ void *aux;
+{
+ struct adb_attach_args * aa_args = (struct adb_attach_args *)aux;
+
+ if (aa_args->origaddr == ADBADDR_MS)
+ return 1;
+ else
+ return 0;
+}
+
+static void
+amsattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ ADBSetInfoBlock adbinfo;
+ struct ams_softc *sc = (struct ams_softc *)self;
+ struct adb_attach_args * aa_args = (struct adb_attach_args *)aux;
+ int error;
+ struct wsmousedev_attach_args a;
+
+ sc->origaddr = aa_args->origaddr;
+ sc->adbaddr = aa_args->adbaddr;
+ sc->handler_id = aa_args->handler_id;
+
+ sc->sc_class = MSCLASS_MOUSE;
+ sc->sc_buttons = 1;
+ sc->sc_res = 100;
+ sc->sc_devid[0] = 0;
+ sc->sc_devid[4] = 0;
+
+ adbinfo.siServiceRtPtr = (Ptr)ms_adbcomplete;
+ adbinfo.siDataAreaAddr = (caddr_t)sc;
+
+ ems_init(sc);
+
+ /* print out the type of mouse we have */
+ switch (sc->handler_id) {
+ case ADBMS_100DPI:
+ printf("%d-button, %d dpi mouse\n", sc->sc_buttons,
+ (int)(sc->sc_res));
+ break;
+ case ADBMS_200DPI:
+ sc->sc_res = 200;
+ printf("%d-button, %d dpi mouse\n", sc->sc_buttons,
+ (int)(sc->sc_res));
+ break;
+ case ADBMS_MSA3:
+ printf("Mouse Systems A3 mouse, %d-button, %d dpi\n",
+ sc->sc_buttons, (int)(sc->sc_res));
+ break;
+ case ADBMS_USPEED:
+ printf("MicroSpeed mouse, default parameters\n");
+ break;
+ case ADBMS_UCONTOUR:
+ printf("Contour mouse, default parameters\n");
+ break;
+ case ADBMS_EXTENDED:
+ if (sc->sc_devid[0] == '\0') {
+ printf("Logitech ");
+ switch (sc->sc_class) {
+ case MSCLASS_MOUSE:
+ printf("MouseMan (non-EMP) mouse");
+ break;
+ case MSCLASS_TRACKBALL:
+ printf("TrackMan (non-EMP) trackball");
+ break;
+ default:
+ printf("non-EMP relative positioning device");
+ break;
+ }
+ printf("\n");
+ } else {
+ printf("EMP ");
+ switch (sc->sc_class) {
+ case MSCLASS_TABLET:
+ printf("tablet");
+ break;
+ case MSCLASS_MOUSE:
+ printf("mouse");
+ break;
+ case MSCLASS_TRACKBALL:
+ printf("trackball");
+ break;
+ case MSCLASS_TRACKPAD:
+ printf("trackpad");
+ break;
+ default:
+ printf("unknown device");
+ break;
+ }
+ printf(" <%s> %d-button, %d dpi\n", sc->sc_devid,
+ sc->sc_buttons, (int)(sc->sc_res));
+ }
+ break;
+ default:
+ printf("relative positioning device (mouse?) (%d)\n",
+ sc->handler_id);
+ break;
+ }
+ error = SetADBInfo(&adbinfo, sc->adbaddr);
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf("ms: returned %d from SetADBInfo\n", error);
+#endif
+
+ a.accessops = &ams_accessops;
+ a.accesscookie = sc;
+ sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
+}
+
+
+/*
+ * Initialize extended mouse support -- probes devices as described
+ * in Inside Macintosh: Devices, Chapter 5 "ADB Manager".
+ *
+ * Extended Mouse Protocol is documented in TechNote HW1:
+ * "ADB - The Untold Story: Space Aliens Ate My Mouse"
+ *
+ * Supports: Extended Mouse Protocol, MicroSpeed Mouse Deluxe,
+ * Mouse Systems A^3 Mouse, Logitech non-EMP MouseMan
+ */
+void
+ems_init(sc)
+ struct ams_softc *sc;
+{
+ int adbaddr, count;
+ short cmd;
+ u_char buffer[9];
+
+ adbaddr = sc->adbaddr;
+ if (sc->origaddr != ADBADDR_MS)
+ return;
+ if (sc->handler_id == ADBMS_USPEED ||
+ sc->handler_id == ADBMS_UCONTOUR) {
+ /* Found MicroSpeed Mouse Deluxe Mac or Contour Mouse */
+ cmd = ((adbaddr<<4)&0xF0)|0x9; /* listen 1 */
+
+ /*
+ * To setup the MicroSpeed or the Contour, it appears
+ * that we can send the following command to the mouse
+ * and then expect data back in the form:
+ * buffer[0] = 4 (bytes)
+ * buffer[1], buffer[2] as std. mouse
+ * buffer[3] = buffer[4] = 0xff when no buttons
+ * are down. When button N down, bit N is clear.
+ * buffer[4]'s locking mask enables a
+ * click to toggle the button down state--sort of
+ * like the "Easy Access" shift/control/etc. keys.
+ * buffer[3]'s alternative speed mask enables using
+ * different speed when the corr. button is down
+ */
+ buffer[0] = 4;
+ buffer[1] = 0x00; /* Alternative speed */
+ buffer[2] = 0x00; /* speed = maximum */
+ buffer[3] = 0x10; /* enable extended protocol,
+ * lower bits = alt. speed mask
+ * = 0000b
+ */
+ buffer[4] = 0x07; /* Locking mask = 0000b,
+ * enable buttons = 0111b
+ */
+ extdms_done = 0;
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ (Ptr)&extdms_done, cmd);
+ while (!extdms_done)
+ /* busy wait until done */;
+
+ sc->sc_buttons = 3;
+ sc->sc_res = 200;
+ return;
+ }
+ if ((sc->handler_id == ADBMS_100DPI) ||
+ (sc->handler_id == ADBMS_200DPI)) {
+ /* found a mouse */
+ cmd = ((adbaddr << 4) & 0xf0) | 0x3;
+
+ extdms_done = 0;
+ cmd = (cmd & 0xf3) | 0x0c; /* talk command */
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ (Ptr)&extdms_done, cmd);
+
+ /* Wait until done, but no more than 2 secs */
+ count = 40000;
+ while (!extdms_done && count-- > 0)
+ delay(50);
+
+ if (!extdms_done) {
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf("adb: extdms_init timed out\n");
+#endif
+ return;
+ }
+
+ /* Attempt to initialize Extended Mouse Protocol */
+ buffer[2] = '\004'; /* make handler ID 4 */
+ extdms_done = 0;
+ cmd = (cmd & 0xf3) | 0x08; /* listen command */
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ (Ptr)&extdms_done, cmd);
+ while (!extdms_done)
+ /* busy wait until done */;
+
+ /*
+ * Check to see if successful, if not
+ * try to initialize it as other types
+ */
+ cmd = ((adbaddr << 4) & 0xf0) | 0x3;
+ extdms_done = 0;
+ cmd = (cmd & 0xf3) | 0x0c; /* talk command */
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ (Ptr)&extdms_done, cmd);
+ while (!extdms_done)
+ /* busy wait until done */;
+
+ if (buffer[2] == ADBMS_EXTENDED) {
+ sc->handler_id = ADBMS_EXTENDED;
+ extdms_done = 0;
+ /* talk register 1 */
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ (Ptr)&extdms_done, (adbaddr << 4) | 0xd);
+ while (!extdms_done)
+ /* busy-wait until done */;
+ if (buffer[0] == 8) {
+ /* we have a true EMP device */
+ sc->sc_class = buffer[7];
+ sc->sc_buttons = buffer[8];
+ sc->sc_res = (int)*(short *)&buffer[5];
+ bcopy(&(buffer[1]), sc->sc_devid, 4);
+ } else if (buffer[1] == 0x9a &&
+ ((buffer[2] == 0x20) || (buffer[2] == 0x21))) {
+ /*
+ * Set up non-EMP Mouseman/Trackman to put
+ * button bits in 3rd byte instead of sending
+ * via pseudo keyboard device.
+ */
+ extdms_done = 0;
+ /* listen register 1 */
+ buffer[0]=2;
+ buffer[1]=0x00;
+ buffer[2]=0x81;
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ (Ptr)&extdms_done, (adbaddr << 4) | 0x9);
+ while (!extdms_done)
+ /* busy-wait until done */;
+ extdms_done = 0;
+ /* listen register 1 */
+ buffer[0]=2;
+ buffer[1]=0x01;
+ buffer[2]=0x81;
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ (Ptr)&extdms_done, (adbaddr << 4) | 0x9);
+ while (!extdms_done)
+ /* busy-wait until done */;
+ extdms_done = 0;
+ /* listen register 1 */
+ buffer[0]=2;
+ buffer[1]=0x02;
+ buffer[2]=0x81;
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ (Ptr)&extdms_done, (adbaddr << 4) | 0x9);
+ while (!extdms_done)
+ /* busy-wait until done */;
+ extdms_done = 0;
+ /* listen register 1 */
+ buffer[0]=2;
+ buffer[1]=0x03;
+ buffer[2]=0x38;
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ (Ptr)&extdms_done, (adbaddr << 4) | 0x9);
+ while (!extdms_done)
+ /* busy-wait until done */;
+ sc->sc_buttons = 3;
+ sc->sc_res = 400;
+ if (buffer[2] == 0x21)
+ sc->sc_class = MSCLASS_TRACKBALL;
+ else
+ sc->sc_class = MSCLASS_MOUSE;
+ } else
+ /* unknown device? */;
+ } else {
+ /* Attempt to initialize as an A3 mouse */
+ buffer[2] = 0x03; /* make handler ID 3 */
+ extdms_done = 0;
+ cmd = (cmd & 0xf3) | 0x08; /* listen command */
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ (Ptr)&extdms_done, cmd);
+ while (!extdms_done)
+ /* busy wait until done */;
+
+ /*
+ * Check to see if successful, if not
+ * try to initialize it as other types
+ */
+ cmd = ((adbaddr << 4) & 0xf0) | 0x3;
+ extdms_done = 0;
+ cmd = (cmd & 0xf3) | 0x0c; /* talk command */
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ (Ptr)&extdms_done, cmd);
+ while (!extdms_done)
+ /* busy wait until done */;
+
+ if (buffer[2] == ADBMS_MSA3) {
+ sc->handler_id = ADBMS_MSA3;
+ /* Initialize as above */
+ cmd = ((adbaddr << 4) & 0xF0) | 0xA;
+ /* listen 2 */
+ buffer[0] = 3;
+ buffer[1] = 0x00;
+ /* Irrelevant, buffer has 0x77 */
+ buffer[2] = 0x07;
+ /*
+ * enable 3 button mode = 0111b,
+ * speed = normal
+ */
+ extdms_done = 0;
+ ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ (Ptr)&extdms_done, cmd);
+ while (!extdms_done)
+ /* busy wait until done */;
+ sc->sc_buttons = 3;
+ sc->sc_res = 300;
+ } else {
+ /* No special support for this mouse */
+ }
+ }
+ }
+}
+
+/*
+ * Handle putting the mouse data received from the ADB into
+ * an ADB event record.
+ */
+void
+ms_adbcomplete(buffer, data_area, adb_command)
+ caddr_t buffer;
+ caddr_t data_area;
+ int adb_command;
+{
+ adb_event_t event;
+ struct ams_softc *msc;
+ int adbaddr;
+#ifdef ADB_DEBUG
+ int i;
+
+ if (adb_debug)
+ printf("adb: transaction completion\n");
+#endif
+
+ adbaddr = (adb_command & 0xf0) >> 4;
+ msc = (struct ams_softc *)data_area;
+
+ if ((msc->handler_id == ADBMS_EXTENDED) && (msc->sc_devid[0] == 0)) {
+ /* massage the data to look like EMP data */
+ if ((buffer[3] & 0x04) == 0x04)
+ buffer[1] &= 0x7f;
+ else
+ buffer[1] |= 0x80;
+ if ((buffer[3] & 0x02) == 0x02)
+ buffer[2] &= 0x7f;
+ else
+ buffer[2] |= 0x80;
+ if ((buffer[3] & 0x01) == 0x01)
+ buffer[3] = 0x00;
+ else
+ buffer[3] = 0x80;
+ }
+
+ event.addr = adbaddr;
+ event.hand_id = msc->handler_id;
+ event.def_addr = msc->origaddr;
+ event.byte_count = buffer[0];
+ memcpy(event.bytes, buffer + 1, event.byte_count);
+
+#ifdef ADB_DEBUG
+ if (adb_debug) {
+ printf("ms: from %d at %d (org %d) %d:", event.addr,
+ event.hand_id, event.def_addr, buffer[0]);
+ for (i = 1; i <= buffer[0]; i++)
+ printf(" %x", buffer[i]);
+ printf("\n");
+ }
+#endif
+
+ microtime(&event.timestamp);
+
+ ms_processevent(&event, msc);
+}
+
+/*
+ * Given a mouse ADB event, record the button settings, calculate the
+ * x- and y-axis motion, and handoff the event to the appropriate subsystem.
+ */
+static void
+ms_processevent(event, msc)
+ adb_event_t *event;
+ struct ams_softc *msc;
+{
+ adb_event_t new_event;
+ int i, button_bit, max_byte, mask, buttons;
+
+ new_event = *event;
+ buttons = 0;
+
+ /*
+ * This should handle both plain ol' Apple mice and mice
+ * that claim to support the Extended Apple Mouse Protocol.
+ */
+ max_byte = event->byte_count;
+ button_bit = 1;
+ switch (event->hand_id) {
+ case ADBMS_USPEED:
+ case ADBMS_UCONTOUR:
+ /* MicroSpeed mouse and Contour mouse */
+ if (max_byte == 4)
+ buttons = (~event->bytes[2]) & 0xff;
+ else
+ buttons = (event->bytes[0] & 0x80) ? 0 : 1;
+ break;
+ case ADBMS_MSA3:
+ /* Mouse Systems A3 mouse */
+ if (max_byte == 3)
+ buttons = (~event->bytes[2]) & 0x07;
+ else
+ buttons = (event->bytes[0] & 0x80) ? 0 : 1;
+ break;
+ default:
+ /* Classic Mouse Protocol (up to 2 buttons) */
+ for (i = 0; i < 2; i++, button_bit <<= 1)
+ /* 0 when button down */
+ if (!(event->bytes[i] & 0x80))
+ buttons |= button_bit;
+ else
+ buttons &= ~button_bit;
+ /* Extended Protocol (up to 6 more buttons) */
+ for (mask = 0x80; i < max_byte;
+ i += (mask == 0x80), button_bit <<= 1) {
+ /* 0 when button down */
+ if (!(event->bytes[i] & mask))
+ buttons |= button_bit;
+ else
+ buttons &= ~button_bit;
+ mask = ((mask >> 4) & 0xf)
+ | ((mask & 0xf) << 4);
+ }
+ break;
+ }
+ new_event.u.m.buttons = msc->sc_mb | buttons;
+ new_event.u.m.dx = ((signed int) (event->bytes[1] & 0x3f)) -
+ ((event->bytes[1] & 0x40) ? 64 : 0);
+ new_event.u.m.dy = ((signed int) (event->bytes[0] & 0x3f)) -
+ ((event->bytes[0] & 0x40) ? 64 : 0);
+
+ if (msc->sc_wsmousedev)
+ wsmouse_input(msc->sc_wsmousedev, new_event.u.m.buttons,
+ new_event.u.m.dx, -new_event.u.m.dy, 0,
+ WSMOUSE_INPUT_DELTA);
+#if NAED > 0
+ aed_input(&new_event);
+#endif
+}
+
+int
+ams_enable(v)
+ void *v;
+{
+ return 0;
+}
+
+int
+ams_ioctl(v, cmd, data, flag, p)
+ void *v;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ return -1;
+}
+
+void
+ams_disable(v)
+ void *v;
+{
+}
diff --git a/sys/arch/powerpc/mac/amsvar.h b/sys/arch/powerpc/mac/amsvar.h
new file mode 100644
index 00000000000..3cce40f2c59
--- /dev/null
+++ b/sys/arch/powerpc/mac/amsvar.h
@@ -0,0 +1,66 @@
+/* $NetBSD: amsvar.h,v 1.4 1999/06/17 06:59:05 tsubai Exp $ */
+
+/*
+ * Copyright (C) 1998 Colin Wood
+ * 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 Colin Wood.
+ * 4. 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 _MACPPC_AMSVAR_H_
+#define _MACPPC_AMSVAR_H_
+
+/*
+ * State info, per mouse instance.
+ */
+struct ams_softc {
+ struct device sc_dev;
+
+ /* ADB info */
+ int origaddr; /* ADB device type (ADBADDR_MS) */
+ int adbaddr; /* current ADB address */
+ int handler_id; /* type of mouse */
+
+ /* Extended Mouse Protocol info, faked for non-EMP mice */
+ u_int8_t sc_class; /* mouse class (mouse, trackball) */
+ u_int8_t sc_buttons; /* number of buttons */
+ u_int32_t sc_res; /* mouse resolution (dpi) */
+ char sc_devid[5]; /* device indentifier */
+
+ int sc_mb; /* current button state */
+ struct device *sc_wsmousedev;
+};
+
+/* EMP device classes */
+#define MSCLASS_TABLET 0
+#define MSCLASS_MOUSE 1
+#define MSCLASS_TRACKBALL 2
+#define MSCLASS_TRACKPAD 3
+
+void ms_adbcomplete __P((caddr_t buffer, caddr_t data_area, int adb_command));
+void ms_handoff __P((adb_event_t *event, struct ams_softc *));
+
+#endif /* _MACPPC_AMSVAR_H_ */
diff --git a/sys/arch/powerpc/mac/keyboard.h b/sys/arch/powerpc/mac/keyboard.h
new file mode 100644
index 00000000000..cb2e9a4c600
--- /dev/null
+++ b/sys/arch/powerpc/mac/keyboard.h
@@ -0,0 +1,208 @@
+/* $NetBSD: keyboard.h,v 1.1 1998/05/15 10:15:54 tsubai Exp $ */
+
+/*-
+ * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo,
+ * Michael L. Finch, Bradley A. Grantham, and
+ * Lawrence A. Kesteloot
+ * 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 Alice Group.
+ * 4. The names of the Alice Group or any of its members may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``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 ALICE GROUP 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.
+ */
+
+#define ADBK_LEFT 0x3B
+#define ADBK_RIGHT 0x3C
+#define ADBK_UP 0x3E
+#define ADBK_DOWN 0x3D
+#define ADBK_PGUP 0x74
+#define ADBK_PGDN 0x79
+#define ADBK_HOME 0x73
+#define ADBK_END 0x77
+#define ADBK_CONTROL 0x36
+#define ADBK_FLOWER 0x37
+#define ADBK_SHIFT 0x38
+#define ADBK_CAPSLOCK 0x39
+#define ADBK_OPTION 0x3A
+#define ADBK_F 0x03
+#define ADBK_O 0x1F
+#define ADBK_P 0x23
+#define ADBK_Q 0x0C
+#define ADBK_V 0x09
+#define ADBK_1 0x12
+#define ADBK_2 0x13
+#define ADBK_3 0x14
+#define ADBK_4 0x15
+#define ADBK_5 0x17
+#define ADBK_6 0x16
+#define ADBK_7 0x1A
+#define ADBK_8 0x1C
+#define ADBK_9 0x19
+#define ADBK_0 0x1D
+
+#define ADBK_KEYVAL(key) ((key) & 0x7f)
+#define ADBK_PRESS(key) (((key) & 0x80) == 0)
+#define ADBK_KEYDOWN(key) (key)
+#define ADBK_KEYUP(key) ((key) | 0x80)
+#define ADBK_MODIFIER(key) ((((key) & 0x7f) == ADBK_SHIFT) || \
+ (((key) & 0x7f) == ADBK_CONTROL) || \
+ (((key) & 0x7f) == ADBK_FLOWER) || \
+ (((key) & 0x7f) == ADBK_OPTION))
+
+#ifndef KEYBOARD_ARRAY
+extern unsigned char keyboard[128][3];
+#else
+unsigned char keyboard[128][3] = {
+ /* Scan code Normal Shifted Controlled */
+ { /* 0x00, */ 'a', 'A', 0x01 },
+ { /* 0x01, */ 's', 'S', 0x13 },
+ { /* 0x02, */ 'd', 'D', 0x04 },
+ { /* 0x03, */ 'f', 'F', 0x06 },
+ { /* 0x04, */ 'h', 'H', 0x08 },
+ { /* 0x05, */ 'g', 'G', 0x07 },
+ { /* 0x06, */ 'z', 'Z', 0x1A },
+ { /* 0x07, */ 'x', 'X', 0x18 },
+ { /* 0x08, */ 'c', 'C', 0x03 },
+ { /* 0x09, */ 'v', 'V', 0x16 },
+ { /* 0x0A, */ 0x00, 0x00, 0x00 },
+ { /* 0x0B, */ 'b', 'B', 0x02 },
+ { /* 0x0C, */ 'q', 'Q', 0x11 },
+ { /* 0x0D, */ 'w', 'W', 0x17 },
+ { /* 0x0E, */ 'e', 'E', 0x05 },
+ { /* 0x0F, */ 'r', 'R', 0x12 },
+ { /* 0x10, */ 'y', 'Y', 0x19 },
+ { /* 0x11, */ 't', 'T', 0x14 },
+ { /* 0x12, */ '1', '!', 0x00 },
+ { /* 0x13, */ '2', '@', 0x00 },
+ { /* 0x14, */ '3', '#', 0x00 },
+ { /* 0x15, */ '4', '$', 0x00 },
+ { /* 0x16, */ '6', '^', 0x1E },
+ { /* 0x17, */ '5', '%', 0x00 },
+ { /* 0x18, */ '=', '+', 0x00 },
+ { /* 0x19, */ '9', '(', 0x00 },
+ { /* 0x1A, */ '7', '&', 0x00 },
+ { /* 0x1B, */ '-', '_', 0x1F },
+ { /* 0x1C, */ '8', '*', 0x00 },
+ { /* 0x1D, */ '0', ')', 0x00 },
+ { /* 0x1E, */ ']', '}', 0x1D },
+ { /* 0x1F, */ 'o', 'O', 0x0F },
+ { /* 0x20, */ 'u', 'U', 0x15 },
+ { /* 0x21, */ '[', '{', 0x1B },
+ { /* 0x22, */ 'i', 'I', 0x09 },
+ { /* 0x23, */ 'p', 'P', 0x10 },
+ { /* 0x24, */ 0x0D, 0x0D, 0x0D },
+ { /* 0x25, */ 'l', 'L', 0x0C },
+ { /* 0x26, */ 'j', 'J', 0x0A },
+ { /* 0x27, */ '\'', '"', 0x00 },
+ { /* 0x28, */ 'k', 'K', 0x0B },
+ { /* 0x29, */ ';', ':', 0x00 },
+ { /* 0x2A, */ '\\', '|', 0x1C },
+ { /* 0x2B, */ ',', '<', 0x00 },
+ { /* 0x2C, */ '/', '?', 0x00 },
+ { /* 0x2D, */ 'n', 'N', 0x0E },
+ { /* 0x2E, */ 'm', 'M', 0x0D },
+ { /* 0x2F, */ '.', '>', 0x00 },
+ { /* 0x30, */ 0x09, 0x09, 0x09 },
+ { /* 0x31, */ ' ', ' ', 0x00 },
+ { /* 0x32, */ '`', '~', 0x00 },
+ { /* 0x33, */ 0x7F, 0x7F, 0x7F }, /* Delete */
+ { /* 0x34, */ 0x00, 0x00, 0x00 },
+ { /* 0x35, */ 0x1B, 0x1B, 0x1B },
+ { /* 0x36, */ 0x00, 0x00, 0x00 },
+ { /* 0x37, */ 0x00, 0x00, 0x00 },
+ { /* 0x38, */ 0x00, 0x00, 0x00 },
+ { /* 0x39, */ 0x00, 0x00, 0x00 },
+ { /* 0x3A, */ 0x00, 0x00, 0x00 },
+ { /* 0x3B, */ 'h', 0x00, 0x00 }, /* Left */
+ { /* 0x3C, */ 'l', 0x00, 0x00 }, /* Right */
+ { /* 0x3D, */ 'j', 0x00, 0x00 }, /* Down */
+ { /* 0x3E, */ 'k', 0x00, 0x00 }, /* Up */
+ { /* 0x3F, */ 0x00, 0x00, 0x00 },
+ { /* 0x40, */ 0x00, 0x00, 0x00 },
+ { /* 0x41, */ '.', '.', 0x00 },
+ { /* 0x42, */ 0x00, 0x00, 0x00 },
+ { /* 0x43, */ '*', '*', 0x00 },
+ { /* 0x44, */ 0x00, 0x00, 0x00 },
+ { /* 0x45, */ '+', '+', 0x00 },
+ { /* 0x46, */ 0x00, 0x00, 0x00 },
+ { /* 0x47, */ 0x00, 0x00, 0x00 },
+ { /* 0x48, */ 0x00, 0x00, 0x00 },
+ { /* 0x49, */ 0x00, 0x00, 0x00 },
+ { /* 0x4A, */ 0x00, 0x00, 0x00 },
+ { /* 0x4B, */ '/', '/', 0x00 },
+ { /* 0x4C, */ 0x0D, 0x0D, 0x0D },
+ { /* 0x4D, */ 0x00, 0x00, 0x00 },
+ { /* 0x4E, */ '-', '-', 0x00 },
+ { /* 0x4F, */ 0x00, 0x00, 0x00 },
+ { /* 0x50, */ 0x00, 0x00, 0x00 },
+ { /* 0x51, */ '=', '=', 0x00 },
+ { /* 0x52, */ '0', '0', 0x00 },
+ { /* 0x53, */ '1', '1', 0x00 },
+ { /* 0x54, */ '2', '2', 0x00 },
+ { /* 0x55, */ '3', '3', 0x00 },
+ { /* 0x56, */ '4', '4', 0x00 },
+ { /* 0x57, */ '5', '5', 0x00 },
+ { /* 0x58, */ '6', '6', 0x00 },
+ { /* 0x59, */ '7', '7', 0x00 },
+ { /* 0x5A, */ 0x00, 0x00, 0x00 },
+ { /* 0x5B, */ '8', '8', 0x00 },
+ { /* 0x5C, */ '9', '9', 0x00 },
+ { /* 0x5D, */ 0x00, 0x00, 0x00 },
+ { /* 0x5E, */ 0x00, 0x00, 0x00 },
+ { /* 0x5F, */ 0x00, 0x00, 0x00 },
+ { /* 0x60, */ 0x00, 0x00, 0x00 },
+ { /* 0x61, */ 0x00, 0x00, 0x00 },
+ { /* 0x62, */ 0x00, 0x00, 0x00 },
+ { /* 0x63, */ 0x00, 0x00, 0x00 },
+ { /* 0x64, */ 0x00, 0x00, 0x00 },
+ { /* 0x65, */ 0x00, 0x00, 0x00 },
+ { /* 0x66, */ 0x00, 0x00, 0x00 },
+ { /* 0x67, */ 0x00, 0x00, 0x00 },
+ { /* 0x68, */ 0x00, 0x00, 0x00 },
+ { /* 0x69, */ 0x00, 0x00, 0x00 },
+ { /* 0x6A, */ 0x00, 0x00, 0x00 },
+ { /* 0x6B, */ 0x00, 0x00, 0x00 },
+ { /* 0x6C, */ 0x00, 0x00, 0x00 },
+ { /* 0x6D, */ 0x00, 0x00, 0x00 },
+ { /* 0x6E, */ 0x00, 0x00, 0x00 },
+ { /* 0x6F, */ 0x00, 0x00, 0x00 },
+ { /* 0x70, */ 0x00, 0x00, 0x00 },
+ { /* 0x71, */ 0x00, 0x00, 0x00 },
+ { /* 0x72, */ 0x00, 0x00, 0x00 },
+ { /* 0x73, */ 0x00, 0x00, 0x00 },
+ { /* 0x74, */ 0x00, 0x00, 0x00 },
+ { /* 0x75, */ 0x00, 0x00, 0x00 },
+ { /* 0x76, */ 0x00, 0x00, 0x00 },
+ { /* 0x77, */ 0x00, 0x00, 0x00 },
+ { /* 0x78, */ 0x00, 0x00, 0x00 },
+ { /* 0x79, */ 0x00, 0x00, 0x00 },
+ { /* 0x7A, */ 0x00, 0x00, 0x00 },
+ { /* 0x7B, */ 0x00, 0x00, 0x00 },
+ { /* 0x7C, */ 0x00, 0x00, 0x00 },
+ { /* 0x7D, */ 0x00, 0x00, 0x00 },
+ { /* 0x7E, */ 0x00, 0x00, 0x00 },
+ { /* 0x7F, */ 0x00, 0x00, 0x00 }
+};
+#endif /* KEYBOARD_ARRAY */