diff options
Diffstat (limited to 'sys/dev/adb')
-rw-r--r-- | sys/dev/adb/adb.h | 163 | ||||
-rw-r--r-- | sys/dev/adb/adb_subr.c | 108 | ||||
-rw-r--r-- | sys/dev/adb/akbd.c | 551 | ||||
-rw-r--r-- | sys/dev/adb/akbdmap.h | 525 | ||||
-rw-r--r-- | sys/dev/adb/akbdvar.h | 72 | ||||
-rw-r--r-- | sys/dev/adb/ams.c | 536 | ||||
-rw-r--r-- | sys/dev/adb/amsvar.h | 64 | ||||
-rw-r--r-- | sys/dev/adb/files.adb | 11 | ||||
-rw-r--r-- | sys/dev/adb/keyboard.h | 217 |
9 files changed, 2247 insertions, 0 deletions
diff --git a/sys/dev/adb/adb.h b/sys/dev/adb/adb.h new file mode 100644 index 00000000000..e18e61cc0ea --- /dev/null +++ b/sys/dev/adb/adb.h @@ -0,0 +1,163 @@ +/* $OpenBSD: adb.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */ +/* $NetBSD: adbsys.h,v 1.4 2000/12/19 02:59:24 tsubai Exp $ */ + +/*- + * Copyright (C) 1993, 1994 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. + */ + +#ifndef _ADB_H_ +#define _ADB_H_ + +#ifdef _KERNEL + +#include <sys/time.h> /* timeval stuff */ + +/* + * Arguments used to attach a device to the Apple Desktop Bus + */ +struct adb_attach_args { + int origaddr; + int adbaddr; + int handler_id; +}; + +#define ADB_CMDADDR(cmd) ((u_int8_t)(cmd & 0xf0) >> 4) +#define ADBFLUSH(dev) ((((u_int8_t)dev & 0x0f) << 4) | 0x01) +#define ADBLISTEN(dev, reg) ((((u_int8_t)dev & 0x0f) << 4) | 0x08 | reg) +#define ADBTALK(dev, reg) ((((u_int8_t)dev & 0x0f) << 4) | 0x0c | reg) + +/* an ADB event */ +typedef struct adb_event_s { + int addr; /* device address */ + int hand_id; /* handler id */ + int def_addr; /* default address */ + int byte_count; /* number of bytes */ + unsigned char bytes[8]; /* bytes from register 0 */ + struct timeval timestamp; /* time event was acquired */ + union { + struct adb_keydata_s { + int key; /* ADB key code */ + } k; + struct adb_mousedata_s { + int dx; /* mouse delta x */ + int dy; /* mouse delta y */ + int buttons; /* buttons (down << (buttonnum)) */ + } m; + } u; /* courtesy interpretation */ +} adb_event_t; + + /* Interesting default addresses */ +#define ADBADDR_SECURE 1 /* Security dongles */ +#define ADBADDR_MAP 2 /* Mapped devices (keyboards/pads) */ +#define ADBADDR_REL 3 /* Relative positioning devices + (mice, trackballs/pads) */ +#define ADBADDR_ABS 4 /* Absolute positioning devices + (graphics tablets) */ +#define ADBADDR_DATATX 5 +#define ADBADDR_RSRVD 6 /* Reserved by Apple */ +#define ADBADDR_MISC 7 /* Miscellaneous appliances */ +#define ADBADDR_DONGLE ADBADDR_SECURE +#define ADBADDR_KBD ADBADDR_MAP +#define ADBADDR_MS ADBADDR_REL +#define ADBADDR_TABLET ADBADDR_ABS +#define ADBADDR_MODEM ADBADDR_DATATX + +#define ADBADDR_APM 0xac0ff /* A faux-addr for the APM driver to + latch onto */ + + /* Interesting keyboard handler IDs */ +#define ADB_STDKBD 1 +#define ADB_EXTKBD 2 +#define ADB_ISOKBD 4 +#define ADB_EXTISOKBD 5 +#define ADB_KBDII 8 +#define ADB_ISOKBDII 9 +#define ADB_PBKBD 12 +#define ADB_PBISOKBD 13 +#define ADB_ADJKPD 14 +#define ADB_ADJKBD 16 +#define ADB_ADJISOKBD 17 +#define ADB_ADJJAPKBD 18 +#define ADB_PBEXTISOKBD 20 +#define ADB_PBEXTJAPKBD 21 +#define ADB_JPKBDII 22 +#define ADB_PBEXTKBD 24 +#define ADB_DESIGNKBD 27 /* XXX Needs to be verified XXX */ +#define ADB_PBJPKBD 30 +#define ADB_PBG4KBD 195 +#define ADB_IBITISOKBD 196 +#define ADB_PBG3JPKBD 201 + + /* Interesting mouse handler IDs */ +#define ADBMS_100DPI 1 +#define ADBMS_200DPI 2 +#define ADBMS_MSA3 3 /* Mouse Systems A3 Mouse */ +#define ADBMS_EXTENDED 4 /* Extended mouse protocol */ +#define ADBMS_USPEED 0x2f /* MicroSpeed mouse */ +#define ADBMS_UCONTOUR 0x66 /* Contour mouse */ +#define ADBMS_TURBO 50 /* Kensington Turbo Mouse */ + + /* Interesting tablet handler ID */ +#define ADB_ARTPAD 58 /* WACOM ArtPad II tablet */ + + /* Interesting miscellaneous handler ID */ +#define ADB_POWERKEY 34 /* Sophisticated Circuits PowerKey */ + /* (intelligent power tap) */ + +extern int adb_polling; +#ifdef ADB_DEBUG +extern int adb_debug; +#endif + +/* ADB Manager */ + +typedef caddr_t Ptr; + +typedef struct { + Ptr siServiceRtPtr; + Ptr siDataAreaAddr; +} ADBSetInfoBlock; + +typedef struct { + unsigned char devType; + unsigned char origADBAddr; + Ptr dbServiceRtPtr; + Ptr dbDataAreaAddr; +} ADBDataBlock; + +int adbprint(void *, const char *); +int adb_op_sync(Ptr, Ptr, Ptr, short); +int set_adb_info(ADBSetInfoBlock *, int); + +#endif /* _KERNEL */ + +#endif /* _ADB_H_ */ diff --git a/sys/dev/adb/adb_subr.c b/sys/dev/adb/adb_subr.c new file mode 100644 index 00000000000..839f2aa6878 --- /dev/null +++ b/sys/dev/adb/adb_subr.c @@ -0,0 +1,108 @@ +/* $OpenBSD: adb_subr.c,v 1.1 2006/01/18 23:21:17 miod Exp $ */ +/* $NetBSD: adb.c,v 1.6 1999/08/16 06:28:09 tsubai 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/systm.h> +#include <sys/device.h> + +#include <dev/adb/adb.h> + +struct cfdriver adb_cd = { + NULL, "adb", DV_DULL +}; + +int +adbprint(void *args, const char *name) +{ + struct adb_attach_args *aa_args = (struct adb_attach_args *)args; + int rv = UNCONF; + + if (name) { /* no configured device matched */ + rv = UNSUPP; /* most ADB device types are unsupported */ + + /* print out what kind of ADB device we have found */ + switch(aa_args->origaddr) { +#ifdef ADBVERBOSE + case ADBADDR_SECURE: + printf("security dongle (%d)", aa_args->handler_id); + break; +#endif + case ADBADDR_MAP: + printf("mapped device (%d)", aa_args->handler_id); + rv = UNCONF; + break; + case ADBADDR_REL: + printf("relative positioning device (%d)", + aa_args->handler_id); + rv = UNCONF; + break; +#ifdef ADBVERBOSE + case ADBADDR_ABS: + switch (aa_args->handler_id) { + case ADB_ARTPAD: + printf("WACOM ArtPad II"); + break; + default: + printf("absolute positioning device (%d)", + aa_args->handler_id); + break; + } + break; + case ADBADDR_DATATX: + printf("data transfer device (modem?) (%d)", + aa_args->handler_id); + break; + case ADBADDR_MISC: + switch (aa_args->handler_id) { + case ADB_POWERKEY: + printf("Sophisticated Circuits PowerKey"); + break; + default: + printf("misc. device (remote control?) (%d)", + aa_args->handler_id); + break; + } + break; + default: + printf("unknown type %d device, (handler %d)", + aa_args->origaddr, aa_args->handler_id); + break; +#endif /* ADBVERBOSE */ + } + printf(" at %s", name); + } + + printf(" addr %d", aa_args->adbaddr); + + return (rv); +} diff --git a/sys/dev/adb/akbd.c b/sys/dev/adb/akbd.c new file mode 100644 index 00000000000..18d8434415e --- /dev/null +++ b/sys/dev/adb/akbd.c @@ -0,0 +1,551 @@ +/* $OpenBSD: akbd.c,v 1.1 2006/01/18 23:21:17 miod Exp $ */ +/* $NetBSD: akbd.c,v 1.17 2005/01/15 16:00:59 chs 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/timeout.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <sys/fcntl.h> +#include <sys/poll.h> +#include <sys/selinfo.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> +#include <machine/cpu.h> + +#include <dev/adb/adb.h> +#include <dev/adb/akbdmap.h> +#include <dev/adb/akbdvar.h> + +#define KEYBOARD_ARRAY +#include <dev/adb/keyboard.h> + +/* + * Function declarations. + */ +int akbdmatch(struct device *, void *, void *); +void akbdattach(struct device *, struct device *, void *); +void kbd_adbcomplete(caddr_t, caddr_t, int); +void kbd_processevent(adb_event_t *, struct akbd_softc *); +#ifdef notyet +u_char getleds(int); +int setleds(struct akbd_softc *, u_char); +void blinkleds(struct akbd_softc *); +#endif + +/* Driver definition. */ +struct cfattach akbd_ca = { + sizeof(struct akbd_softc), akbdmatch, akbdattach +}; +struct cfdriver akbd_cd = { + NULL, "akbd", DV_DULL +}; + +int akbd_enable(void *, int); +void akbd_set_leds(void *, int); +int akbd_ioctl(void *, u_long, caddr_t, int, struct proc *); +int akbd_intr(adb_event_t *, struct akbd_softc *); +void akbd_rawrepeat(void *v); + + +struct wskbd_accessops akbd_accessops = { + akbd_enable, + akbd_set_leds, + akbd_ioctl, +}; + +struct wskbd_mapdata akbd_keymapdata = { + akbd_keydesctab, +#ifdef AKBD_LAYOUT + AKBD_LAYOUT, +#else + KB_US, +#endif +}; + +int +akbdmatch(struct device *parent, void *vcf, void *aux) +{ + struct adb_attach_args *aa_args = (struct adb_attach_args *)aux; + + if (aa_args->origaddr == ADBADDR_KBD) + return 1; + else + return 0; +} + +void +akbdattach(struct device *parent, struct device *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 error, kbd_done; + short cmd; + u_char buffer[9]; + struct wskbddev_attach_args a; + static int akbd_console_initted; + int wskbd_eligible = 1; + + 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; + + printf(": "); + 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: + cmd = ADBTALK(sc->adbaddr, 1); + kbd_done = + (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0); + + /* 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; + wskbd_eligible = 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; + wskbd_eligible = 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"); + wskbd_eligible = 0; + 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; + case ADB_PBJPKBD: + printf("PowerBook keyboard (Japanese layout)\n"); + break; + case ADB_PBG3JPKBD: + printf("PowerBook G3 keyboard (Japanese layout)\n"); + break; + case ADB_PBG4KBD: + printf("PowerBook G4 keyboard (Inverted T)\n"); + break; + case ADB_IBITISOKBD: + printf("iBook keyboard with inverted T (ISO layout)\n"); + break; + default: + printf("mapped device (%d)\n", sc->handler_id); + wskbd_eligible = 0; + break; + } + error = set_adb_info(&adbinfo, sc->adbaddr); +#ifdef ADB_DEBUG + if (adb_debug) + printf("akbd: returned %d from set_adb_info\n", error); +#endif + +#ifdef WSDISPLAY_COMPAT_RAWKBD + timeout_set(&sc->sc_rawrepeat_ch, akbd_rawrepeat, sc); +#endif + + if (akbd_is_console() && wskbd_eligible) + a.console = (++akbd_console_initted == 1); + else + a.console = 0; + 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(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_CMDADDR(adb_command); + 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("akbd: 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. + */ +void +kbd_processevent(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; + if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */ + akbd_intr(&new_event, ksc); + 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; + if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */ + akbd_intr(&new_event, ksc); + } + +} + +#ifdef notyet +/* + * Get the actual hardware LED state and convert it to softc format. + */ +u_char +getleds(int addr) +{ + short cmd; + u_char buffer[9], leds; + + leds = 0x00; /* all off */ + buffer[0] = 0; + + cmd = ADBTALK(addr, 2); + if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0 && + 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 + */ +int +setleds(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; + + cmd = ADBTALK(addr, 2); + if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) || buffer[0] == 0) + return (EIO); + + leds = ~leds & 0x07; + buffer[2] &= 0xf8; + buffer[2] |= leds; + + cmd = ADBLISTEN(addr, 2); + adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd); + + /* talk R2 */ + cmd = ADBTALK(addr, 2); + if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) || 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. + */ +void +blinkleds(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(void *v, int on) +{ + return 0; +} + +void +akbd_set_leds(void *v, int on) +{ +} + +int +akbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) +{ +#ifdef WSDISPLAY_COMPAT_RAWKBD + struct akbd_softc *sc = v; +#endif + + switch (cmd) { + + case WSKBDIO_GTYPE: + *(int *)data = WSKBD_TYPE_ADB; + return 0; + case WSKBDIO_SETLEDS: + return 0; + case WSKBDIO_GETLEDS: + *(int *)data = 0; + return 0; +#ifdef WSDISPLAY_COMPAT_RAWKBD + case WSKBDIO_SETMODE: + sc->sc_rawkbd = *(int *)data == WSKBD_RAW; + timeout_del(&sc->sc_rawrepeat_ch); + return (0); +#endif + +#ifdef mac68k /* XXX not worth creating akbd_machdep_ioctl() */ + case WSKBDIO_BELL: + case WSKBDIO_COMPLEXBELL: +#define d ((struct wskbd_bell_data *)data) + mac68k_ring_bell(d->pitch, d->period * hz / 1000, d->volume); +#undef d + return (0); +#endif + + default: + return (-1); + } +} + +#ifdef WSDISPLAY_COMPAT_RAWKBD +void +akbd_rawrepeat(void *v) +{ + struct akbd_softc *sc = v; + int s; + + s = spltty(); + wskbd_rawinput(sc->sc_wskbddev, sc->sc_rep, sc->sc_nrep); + splx(s); + timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000); +} +#endif + +int adb_polledkey; +int +akbd_intr(adb_event_t *event, struct akbd_softc *sc) +{ + int key, press, val; + int type; + static int shift; + + key = event->u.k.key; + + /* + * Caps lock is weird. The key sequence generated is: + * press: down(57) [57] (LED turns on) + * release: up(127) [255] + * press: up(127) [255] + * release: up(57) [185] (LED turns off) + */ + if (ADBK_KEYVAL(key) == ADBK_CAPSLOCK) + shift = 0; + + if (key == 255) { + if (shift == 0) { + key = ADBK_KEYUP(ADBK_CAPSLOCK); + shift = 1; + } else { + key = ADBK_KEYDOWN(ADBK_CAPSLOCK); + shift = 0; + } + } + + press = ADBK_PRESS(key); + val = ADBK_KEYVAL(key); + + type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; + + if (adb_polling) { + adb_polledkey = key; +#ifdef WSDISPLAY_COMPAT_RAWKBD + } else if (sc->sc_rawkbd) { + char cbuf[MAXKEYS *2]; + int c, j, s; + int npress; + + j = npress = 0; + + c = keyboard[val][3]; + if (c == 0) { + return 0; /* XXX */ + } + if (c & 0x80) + cbuf[j++] = 0xe0; + cbuf[j] = c & 0x7f; + if (type == WSCONS_EVENT_KEY_UP) { + cbuf[j] |= 0x80; + } else { + /* this only records last key pressed */ + if (c & 0x80) + sc->sc_rep[npress++] = 0xe0; + sc->sc_rep[npress++] = c & 0x7f; + } + j++; + s = spltty(); + wskbd_rawinput(sc->sc_wskbddev, cbuf, j); + splx(s); + timeout_del(&sc->sc_rawrepeat_ch); + sc->sc_nrep = npress; + if (npress != 0) + timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAY1/1000); + return 0; +#endif + } else { + wskbd_input(sc->sc_wskbddev, type, val); + } + + return 0; +} diff --git a/sys/dev/adb/akbdmap.h b/sys/dev/adb/akbdmap.h new file mode 100644 index 00000000000..f91444ed71a --- /dev/null +++ b/sys/dev/adb/akbdmap.h @@ -0,0 +1,525 @@ +/* $OpenBSD: akbdmap.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */ +/* $NetBSD: akbdmap.h,v 1.7 2005/05/05 22:29:41 abs 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(52), KS_KP_Enter, + 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_Num_Lock, 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, KS_KP_Insert, + KC(83), KS_KP_1, KS_KP_End, + KC(84), KS_KP_2, KS_KP_Down, + KC(85), KS_KP_3, KS_KP_Next, + KC(86), KS_KP_4, KS_KP_Left, + KC(87), KS_KP_5, KS_KP_Begin, + KC(88), KS_KP_6, KS_KP_Right, + KC(89), KS_KP_7, KS_KP_Home, + + KC(91), KS_KP_8, KS_KP_Up, + KC(92), KS_KP_9, KS_KP_Prior, + + KC(95), KS_KP_Decimal, KS_KP_Delete, + KC(96), KS_f5, + KC(97), KS_f6, + KC(98), KS_f7, + KC(99), KS_f3, + KC(100), KS_f8, + + KC(101), KS_f9, + + KC(103), KS_f11, + + KC(105), KS_f13, KS_Print_Screen, + KC(106), KS_KP_Enter, + KC(107), KS_f14, KS_Hold_Screen, + + KC(109), KS_f10, + + KC(111), KS_f12, + + KC(113), KS_f15, KS_Pause, + KC(114), KS_Insert, + KC(115), KS_Home, + KC(116), KS_Prior, + KC(117), KS_Delete, + KC(118), KS_f4, + KC(119), KS_End, + KC(120), KS_f2, + KC(121), KS_Next, + KC(122), KS_f1, + + KC(127), KS_Cmd_Debugger, +}; + +static const keysym_t akbd_keydesc_fr[] = { +/* pos normal shifted altgr shift-altgr */ + KC(0), KS_q, + KC(1), KS_s, KS_S, KS_Ograve, + KC(4), KS_h, KS_H, KS_Igrave, KS_Icircumflex, + KC(6), KS_w, KS_W, KS_less, KS_greater, + KC(8), KS_c, KS_C, KS_copyright, KS_cent, + KC(10), KS_at, KS_numbersign, + KC(11), KS_b, KS_B, KS_ssharp, + KC(12), KS_a, KS_A, KS_ae, KS_AE, + KC(13), KS_z, KS_Z, KS_Acircumflex, KS_Aring, + KC(14), KS_e, KS_E, KS_ecircumflex, KS_Ecircumflex, + KC(15), KS_r, KS_R, KS_registered, KS_comma, + KC(16), KS_y, KS_Y, KS_Uacute, + KC(18), KS_ampersand, KS_1, KS_voidSymbol, KS_dead_acute, + KC(19), KS_eacute, KS_2, KS_ediaeresis, + KC(20), KS_quotedbl, KS_3, + KC(21), KS_apostrophe, KS_4, KS_braceleft, KS_bracketleft, + KC(22), KS_section, KS_6, KS_paragraph, KS_aring, + KC(23), KS_parenleft, KS_5, KS_braceleft, KS_bracketleft, + KC(24), KS_minus, KS_underscore, KS_braceright, + KC(25), KS_ccedilla, KS_9, KS_Ccedilla, KS_Aacute, + KC(26), KS_egrave, KS_7, KS_guillemotleft, + KS_guillemotright, + KC(27), KS_parenright, KS_degree, KS_braceright, KS_bracketright, + KC(28), KS_exclam, KS_8, KS_exclamdown, KS_Ucircumflex, + KC(29), KS_agrave, KS_0, KS_oslash, KS_Ooblique, + KC(30), KS_dollar, KS_asterisk, KS_cent, KS_yen, + KC(33), KS_dead_circumflex, KS_dead_diaeresis, + KS_ocircumflex, KS_Ocircumflex, + KC(34), KS_i, KS_I, KS_icircumflex, KS_idiaeresis, + KC(37), KS_l, KS_L, KS_notsign, KS_bar, + KC(38), KS_j, KS_J, KS_Idiaeresis, KS_Iacute, + KC(39), KS_ugrave, KS_percent, KS_Ugrave, + KC(40), KS_k, KS_K, KS_Egrave, KS_Ediaeresis, + KC(41), KS_m, KS_M, KS_mu, KS_Oacute, + KC(42), KS_dead_grave, KS_sterling, KS_at, KS_numbersign, + KC(43), KS_semicolon, KS_period, + KC(44), KS_equal, KS_plus, KS_voidSymbol, KS_plusminus, + KC(45), KS_n, KS_N, KS_dead_tilde, + KC(46), KS_comma, KS_question, KS_voidSymbol, KS_questiondown, + KC(47), KS_colon, KS_slash, KS_division, KS_backslash, + KC(50), KS_less, KS_greater, + KC(52), KS_Alt_R, + KC(55), KS_Meta_L, /* Command */ + KC(58), KS_Mode_switch, KS_Multi_key, /* Option */ +}; + +static const keysym_t akbd_keydesc_fr_nodead[] = { + KC(18), KS_ampersand, KS_1, KS_voidSymbol, KS_acute, + KC(33), KS_asciicircum, KS_diaeresis, KS_ocircumflex, KS_Ocircumflex, + KC(42), KS_grave, KS_sterling, KS_at, KS_numbersign, + KC(45), KS_n, KS_N, KS_asciitilde, +}; + +static const keysym_t akbd_keydesc_jp[] = { +/* pos command normal shifted */ + KC(19), KS_2, KS_quotedbl, + KC(22), KS_6, KS_ampersand, + KC(24), KS_asciicircum, KS_asciitilde, + KC(25), KS_9, KS_parenright, + KC(26), KS_7, KS_apostrophe, + KC(27), KS_minus, KS_equal, + KC(28), KS_8, KS_parenleft, + KC(29), KS_0, + KC(30), KS_bracketleft, KS_braceleft, + KC(33), KS_at, KS_grave, + KC(39), KS_colon, KS_asterisk, + + KC(41), KS_semicolon, KS_plus, + KC(42), KS_bracketright,KS_braceright, + KC(93), KS_backslash, KS_bar, + KC(94), KS_underscore, +}; + +static const keysym_t akbd_keydesc_uk[] = { +/* pos normal shifted altgr shift-altgr */ + KC(10), KS_section, KS_plusminus, + KC(20), KS_3, KS_sterling, KS_numbersign, + KC(52), KS_KP_Enter, + KC(58), KS_Mode_switch, KS_Multi_key, /* Option */ +}; + +static const keysym_t akbd_keydesc_sv[] = { +/* pos normal shifted altgr shift-altgr */ + KC(10), KS_section, KS_degree, + KC(19), KS_2, KS_quotedbl, KS_at, + KC(21), KS_4, KS_dollar, + KC(22), KS_6, KS_ampersand, + KC(24), KS_dead_acute, KS_dead_grave, + KC(25), KS_9, KS_parenright, KS_bracketright, + KC(26), KS_7, KS_slash, KS_braceleft, + KC(27), KS_plus, KS_question, KS_backslash, + KC(28), KS_8, KS_parenleft, KS_bracketleft, + KC(29), KS_0, KS_equal, KS_braceright, + KC(30), KS_dead_diaeresis,KS_dead_circumflex,KS_dead_tilde, + KC(33), KS_aring, + KC(39), KS_adiaeresis, + KC(41), KS_odiaeresis, + KC(42), KS_apostrophe, KS_asterisk, + KC(43), KS_comma, KS_semicolon, + KC(44), KS_minus, KS_underscore, + KC(47), KS_period, KS_colon, + KC(50), KS_less, KS_greater, KS_bar, + KC(58), KS_Mode_switch,KS_Multi_key, +}; + +static const keysym_t akbd_keydesc_sv_nodead[] = { +/* pos normal shifted altgr shift-altgr */ + KC(24), KS_apostrophe, KS_grave, + KC(30), KS_diaeresis, KS_asciicircum, KS_asciitilde, +}; + +static const keysym_t akbd_keydesc_de[] = { +/* pos normal shifted altgr shift-altgr */ + KC(0), KS_a, KS_A, KS_aring, KS_Aring, + KC(1), KS_s, KS_S, KS_voidSymbol, KS_Iacute, + KC(3), KS_f, KS_F, KS_voidSymbol, KS_Idiaeresis, + KC(4), KS_h, KS_H, KS_ordfeminine, KS_Oacute, + KC(5), KS_g, KS_G, KS_copyright, KS_Igrave, + KC(6), KS_y, KS_Y, KS_yen, + KC(7), KS_x, KS_X, KS_voidSymbol, KS_Ugrave, + KC(8), KS_c, KS_C, KS_ccedilla, KS_Ccedilla, + KC(10), KS_dead_circumflex,KS_degree, + KC(12), KS_q, KS_Q, KS_guillemotleft,KS_guillemotright, + KC(15), KS_r, KS_R, KS_registered, KS_cedilla, + KC(16), KS_z, KS_Z, + KC(18), KS_1, KS_exclam, KS_exclamdown, KS_notsign, + KC(19), KS_2, KS_quotedbl, + KC(20), KS_3, KS_section, KS_paragraph, KS_numbersign, + KC(21), KS_4, KS_dollar, KS_cent, KS_sterling, + KC(22), KS_6, KS_ampersand, KS_bracketright,KS_dead_circumflex, + KC(23), KS_5, KS_percent, KS_bracketleft, + KC(24), KS_dead_acute, KS_dead_grave, KS_apostrophe, + KC(25), KS_9, KS_parenright, KS_braceright, KS_periodcentered, + KC(26), KS_7, KS_slash, KS_bar, KS_backslash, + KC(27), KS_ssharp, KS_question, KS_questiondown, + KC(28), KS_8, KS_parenleft, KS_braceleft, + KC(29), KS_0, KS_equal, KS_voidSymbol, KS_macron, + KC(30), KS_plus, KS_asterisk, KS_plusminus, + KC(31), KS_o, KS_O, KS_oslash, KS_Ooblique, + KC(32), KS_u, KS_U, KS_dead_diaeresis,KS_Aacute, + KC(33), KS_udiaeresis, KS_Udiaeresis, KS_voidSymbol, KS_degree, + KC(34), KS_i, KS_I, KS_voidSymbol, KS_Ucircumflex, + KC(37), KS_l, KS_L, KS_at, + KC(38), KS_j, KS_J, KS_masculine, + KC(39), KS_adiaeresis, KS_Adiaeresis, KS_ae, KS_AE, + KC(41), KS_odiaeresis, KS_Odiaeresis, + KC(42), KS_numbersign, KS_apostrophe, + KC(43), KS_comma, KS_semicolon, + KC(44), KS_minus, KS_underscore, + KC(45), KS_n, KS_N, KS_dead_tilde, + KC(46), KS_m, KS_M, KS_mu, + KC(47), KS_period, KS_colon, + KC(50), KS_less, KS_greater, + KC(52), KS_Multi_key, + KC(58), KS_Mode_switch, +}; + +static const keysym_t akbd_keydesc_de_nodead[] = { +/* pos normal shifted altgr shift-altgr */ + KC(10), KS_asciicircum, KS_degree, + KC(22), KS_6, KS_ampersand, KS_bracketright,KS_asciicircum, + KC(24), KS_acute, KS_grave, KS_apostrophe, + KC(32), KS_u, KS_U, KS_diaeresis, KS_Aacute, + KC(45), KS_n, KS_N, KS_asciitilde, +}; + +static const keysym_t akbd_keydesc_sf[] = { +/* pos normal shifted altgr shift-altgr */ + KC(6), KS_y, + KC(10), KS_paragraph, KS_degree, + KC(16), KS_z, + KC(18), KS_plus, KS_1, + KC(19), KS_quotedbl, KS_2, + KC(20), KS_asterisk, KS_3, + KC(21), KS_ccedilla, KS_4, KS_Ccedilla, + KC(22), KS_ampersand, KS_6, + KC(23), KS_percent, KS_5, + KC(24), KS_dead_circumflex,KS_grave, + KC(25), KS_parenright, KS_9, + KC(26), KS_slash, KS_7, + KC(27), KS_apostrophe, KS_question, + KC(28), KS_parenleft, KS_8, + KC(29), KS_equal, KS_0, + KC(30), KS_dead_diaeresis,KS_exclam, + KC(33), KS_egrave, KS_udiaeresis, + KC(39), KS_agrave, KS_adiaeresis, + KC(41), KS_eacute, KS_odiaeresis, + KC(42), KS_dollar, KS_sterling, + KC(43), KS_period, KS_colon, + KC(46), KS_comma, KS_semicolon, + KC(47), KS_minus, KS_underscore, + KC(50), KS_less, KS_greater, +}; + +static const keysym_t akbd_keydesc_es[] = { +/* pos normal shifted altgr shift-altgr */ + KC(10), KS_degree, KS_ordfeminine, KS_backslash, + KC(18), KS_1, KS_exclam, KS_bar, + KC(19), KS_2, KS_quotedbl, KS_at, + KC(20), KS_3, KS_periodcentered, KS_numbersign, + KC(21), KS_4, KS_dollar, KS_asciitilde, + KC(22), KS_6, KS_ampersand, KS_notsign, + KC(23), KS_5, KS_percent, + KC(24), KS_exclamdown, KS_questiondown, + KC(25), KS_9, KS_parenright, + KC(26), KS_7, KS_slash, + KC(27), KS_apostrophe, KS_question, + KC(28), KS_8, KS_parenleft, + KC(29), KS_0, KS_equal, + KC(30), KS_plus, KS_asterisk, KS_bracketright, + KC(33), KS_dead_grave, KS_dead_circumflex, KS_bracketleft, + KC(39), KS_dead_acute, KS_dead_diaeresis, KS_braceleft, + KC(41), KS_ntilde, + KC(42), KS_ccedilla, KS_Ccedilla, KS_braceright, + KC(43), KS_comma, KS_semicolon, + KC(44), KS_minus, KS_underscore, + KC(47), KS_period, KS_colon, + KC(50), KS_less, KS_greater, + KC(55), KS_Alt_L, /* Command */ + KC(58), KS_Mode_switch, KS_Multi_key, /* Option */ +}; + +static const keysym_t akbd_keydesc_pt[] = { +/* pos normal shifted altgr shift-altgr */ + KC(7), KS_x, KS_X, KS_guillemotleft, KS_guillemotright, + KC(10), KS_section, KS_plusminus, + KC(19), KS_2, KS_quotedbl, KS_at, + KC(20), KS_3, KS_numbersign, KS_sterling, + KC(22), KS_6, KS_ampersand, + KC(24), KS_plus, KS_asterisk, + KC(25), KS_9, KS_parenright, KS_bracketright, KS_braceright, + KC(26), KS_7, KS_slash, + KC(27), KS_apostrophe, KS_question, + KC(28), KS_8, KS_parenleft, KS_bracketleft, KS_braceleft, + KC(29), KS_0, KS_equal, + KC(30), KS_dead_acute, KS_dead_grave, + KC(33), KS_masculine, KS_ordfeminine, + KC(39), KS_dead_tilde, KS_dead_circumflex, + KC(41), KS_ccedilla, KS_Ccedilla, + KC(43), KS_comma, KS_semicolon, + KC(44), KS_minus, KS_underscore, + KC(47), KS_period, KS_colon, + KC(50), KS_less, KS_greater, + KC(58), KS_Mode_switch, KS_Multi_key, /* Option */ +}; + +static const keysym_t akbd_keydesc_us_dvorak[] = { +/* pos command normal shifted */ + KC(1), KS_o, + KC(2), KS_e, + KC(3), KS_u, + KC(4), KS_d, + KC(5), KS_i, + KC(6), KS_semicolon, KS_colon, + KC(7), KS_q, + KC(8), KS_j, + KC(9), KS_k, + KC(11), KS_x, + KC(12), KS_apostrophe, KS_quotedbl, + KC(13), KS_comma, KS_less, + KC(14), KS_period, KS_greater, + KC(15), KS_p, + KC(16), KS_f, + KC(17), KS_y, + KC(24), KS_bracketright, KS_braceright, + KC(27), KS_bracketleft, KS_braceleft, + KC(30), KS_equal, KS_plus, + KC(31), KS_r, + KC(32), KS_g, + KC(33), KS_slash, KS_question, + KC(34), KS_c, + KC(35), KS_l, + KC(37), KS_n, + KC(38), KS_h, + KC(39), KS_minus, KS_underscore, + KC(40), KS_t, + KC(41), KS_s, + KC(43), KS_w, + KC(44), KS_z, + KC(45), KS_b, + KC(47), KS_v, +}; + +static const keysym_t akbd_keydesc_sg[] = { +/* pos normal shifted altgr shift-altgr */ + KC(0), KS_a, KS_A, KS_aring, KS_Aring, + KC(1), KS_s, KS_S, KS_ssharp, KS_voidSymbol, + KC(3), KS_f, KS_F, KS_section, KS_voidSymbol, + KC(4), KS_h, KS_H, KS_ordfeminine, KS_periodcentered, + KC(5), KS_g, KS_G, KS_at, KS_comma, + KC(6), KS_y, KS_Y, KS_yen, KS_ydiaeresis, + KC(7), KS_x, KS_X, KS_voidSymbol, KS_ydiaeresis, + KC(8), KS_c, KS_C, KS_copyright, + KC(10), KS_section, KS_degree, + KC(12), KS_q, KS_Q, + KC(15), KS_r, KS_R, KS_registered, KS_Egrave, + KC(16), KS_z, KS_Z, KS_voidSymbol, KS_Aacute, + KC(18), KS_1, KS_plus, KS_plusminus, KS_onesuperior, + KC(19), KS_2, KS_quotedbl, KS_twosuperior, + KC(20), KS_3, KS_asterisk, KS_numbersign, KS_threesuperior, + KC(21), KS_4, KS_ccedilla, KS_Ccedilla, + KC(22), KS_6, KS_ampersand, KS_bracketright, + KC(23), KS_5, KS_percent, KS_bracketleft, + KC(24), KS_dead_circumflex,KS_dead_grave,KS_dead_acute, KS_asciitilde, + KC(25), KS_9, KS_parenright, KS_braceright, KS_Ocircumflex, + KC(26), KS_7, KS_slash, KS_bar, KS_backslash, + KC(27), KS_apostrophe, KS_question, KS_questiondown, + KC(28), KS_8, KS_parenleft, KS_braceleft, KS_Ograve, + KC(29), KS_0, KS_equal, KS_voidSymbol, KS_Uacute, + KC(30), KS_dead_diaeresis,KS_exclam, KS_bracketright, + KC(31), KS_o, KS_O, KS_oslash, + KC(32), KS_u, KS_U, KS_degree, KS_Ugrave, + KC(33), KS_udiaeresis, KS_egrave, KS_bracketleft, + KC(34), KS_i, KS_I, KS_exclamdown, + KC(37), KS_l, KS_L, KS_notsign, + KC(38), KS_j, KS_J, KS_masculine, + KC(39), KS_adiaeresis, KS_agrave, KS_ae, KS_AE, + KC(41), KS_odiaeresis, KS_eacute, KS_cent, + KC(42), KS_dollar, KS_sterling, KS_paragraph, + KC(43), KS_comma, KS_semicolon, KS_guillemotleft,KS_guillemotright, + KC(44), KS_minus, KS_underscore, + KC(45), KS_n, KS_N, KS_dead_tilde, + KC(46), KS_m, KS_M, KS_mu, + KC(47), KS_period, KS_colon, KS_voidSymbol, KS_division, + KC(50), KS_less, KS_greater, + KC(52), KS_Multi_key, + KC(58), KS_Mode_switch, +}; + +static const keysym_t akbd_keydesc_sg_nodead[] = { +/* pos normal shifted altgr shift-altgr */ + KC(24), KS_asciicircum, KS_grave, KS_acute, KS_asciitilde, + KC(30), KS_diaeresis, KS_exclam, KS_bracketright,KS_braceright, + KC(45), KS_n, KS_N, KS_asciitilde, +}; + +#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_US | KB_DVORAK, KB_US, akbd_keydesc_us_dvorak), + KBD_MAP(KB_DE, KB_US, akbd_keydesc_de), + KBD_MAP(KB_DE | KB_NODEAD, KB_DE, akbd_keydesc_de_nodead), + KBD_MAP(KB_ES, KB_US, akbd_keydesc_es), + KBD_MAP(KB_FR, KB_US, akbd_keydesc_fr), + KBD_MAP(KB_FR | KB_NODEAD, KB_FR, akbd_keydesc_fr_nodead), + KBD_MAP(KB_JP, KB_US, akbd_keydesc_jp), + KBD_MAP(KB_PT, KB_US, akbd_keydesc_pt), + KBD_MAP(KB_SF, KB_US, akbd_keydesc_sf), + KBD_MAP(KB_SG, KB_US, akbd_keydesc_sg), + KBD_MAP(KB_SG | KB_NODEAD, KB_SG, akbd_keydesc_sg_nodead), + KBD_MAP(KB_SV, KB_US, akbd_keydesc_sv), + KBD_MAP(KB_SV | KB_NODEAD, KB_SV, akbd_keydesc_sv_nodead), + KBD_MAP(KB_UK, KB_US, akbd_keydesc_uk), + {0, 0, 0, 0} +}; + +#undef KBD_MAP +#undef KC diff --git a/sys/dev/adb/akbdvar.h b/sys/dev/adb/akbdvar.h new file mode 100644 index 00000000000..d3c2db3bb2b --- /dev/null +++ b/sys/dev/adb/akbdvar.h @@ -0,0 +1,72 @@ +/* $OpenBSD: akbdvar.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */ +/* $NetBSD: akbdvar.h,v 1.4 1999/02/17 14:56:56 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 _ADB_AKBDVAR_H_ +#define _ADB_AKBDVAR_H_ + +/* + * State info, per keyboard instance. + */ +struct akbd_softc { + struct device sc_dev; + + /* ADB info */ + int origaddr; /* ADB device type (ADBADDR_KBD) */ + int adbaddr; /* current ADB address */ + int handler_id; /* type of keyboard */ + + u_int8_t sc_leds; /* current LED state */ + struct device *sc_wskbddev; +#ifdef WSDISPLAY_COMPAT_RAWKBD +#define MAXKEYS 20 +#define REP_DELAY1 400 +#define REP_DELAYN 100 + int sc_rawkbd; + int sc_nrep; + char sc_rep[MAXKEYS]; + struct timeout sc_rawrepeat_ch; +#endif /* defined(WSDISPLAY_COMPAT_RAWKBD) */ +}; + +/* LED register bits, inverse of actual register value */ +#define LED_NUMLOCK 0x1 +#define LED_CAPSLOCK 0x2 +#define LED_SCROLL_LOCK 0x4 + +int akbd_cnattach(void); +int akbd_is_console(void); + +extern struct wskbd_mapdata akbd_keymapdata; +extern int adb_polledkey; + +#endif /* _ADB_AKBDVAR_H_ */ diff --git a/sys/dev/adb/ams.c b/sys/dev/adb/ams.c new file mode 100644 index 00000000000..97edff1b7a5 --- /dev/null +++ b/sys/dev/adb/ams.c @@ -0,0 +1,536 @@ +/* $OpenBSD: ams.c,v 1.1 2006/01/18 23:21:17 miod Exp $ */ +/* $NetBSD: ams.c,v 1.11 2000/12/19 03:13:40 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/selinfo.h> +#include <sys/proc.h> +#include <sys/signalvar.h> +#include <sys/systm.h> + +#include <machine/autoconf.h> + +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsmousevar.h> + +#include <dev/adb/adb.h> +#include <dev/adb/amsvar.h> + +/* + * Function declarations. + */ +int amsmatch(struct device *, void *, void *); +void amsattach(struct device *, struct device *, void *); + +/* Driver definition. */ +struct cfattach ams_ca = { + sizeof(struct ams_softc), amsmatch, amsattach +}; +/* Driver definition. */ +struct cfdriver ams_cd = { + NULL, "ams", DV_DULL +}; + +int ams_enable(void *); +int ams_ioctl(void *, u_long, caddr_t, int, struct proc *); +void ams_disable(void *); + +const struct wsmouse_accessops ams_accessops = { + ams_enable, + ams_ioctl, + ams_disable, +}; + +void ems_init(struct ams_softc *); +void ms_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command); +void ms_handoff(adb_event_t *event, struct ams_softc *); +void ms_processevent(adb_event_t *event, struct ams_softc *); + +int +amsmatch(struct device *parent, void *cf, void *aux) +{ + struct adb_attach_args *aa_args = aux; + + if (aa_args->origaddr == ADBADDR_MS) + return 1; + else + return 0; +} + +void +amsattach(struct device *parent, struct device *self, void *aux) +{ + ADBSetInfoBlock adbinfo; + struct ams_softc *sc = (struct ams_softc *)self; + struct adb_attach_args *aa_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 */ + printf(": "); + switch (sc->handler_id) { + case ADBMS_200DPI: + sc->sc_res = 200; + /* FALLTHROUGH */ + case ADBMS_100DPI: + 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_TURBO: + printf("Kensington Turbo Mouse\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 = set_adb_info(&adbinfo, sc->adbaddr); +#ifdef ADB_DEBUG + if (adb_debug) + printf("ams: returned %d from set_adb_info\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(struct ams_softc *sc) +{ + int adbaddr; + 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 = ADBLISTEN(adbaddr, 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 + */ + adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd); + + sc->sc_buttons = 3; + sc->sc_res = 200; + return; + } + if (sc->handler_id == ADBMS_TURBO) { + /* Found Kensington Turbo Mouse */ + static u_char data1[] = + { 8, 0xe7, 0x8c, 0, 0, 0, 0xff, 0xff, 0x94 }; + static u_char data2[] = + { 8, 0xa5, 0x14, 0, 0, 0x69, 0xff, 0xff, 0x27 }; + + buffer[0] = 0; + adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, ADBFLUSH(adbaddr)); + + adb_op_sync((Ptr)data1, (Ptr)0, (Ptr)0, ADBLISTEN(adbaddr, 2)); + + buffer[0] = 0; + adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, ADBFLUSH(adbaddr)); + + adb_op_sync((Ptr)data2, (Ptr)0, (Ptr)0, ADBLISTEN(adbaddr, 2)); + return; + } + if ((sc->handler_id == ADBMS_100DPI) || + (sc->handler_id == ADBMS_200DPI)) { + /* found a mouse */ + cmd = ADBTALK(adbaddr, 3); + if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd)) { +#ifdef ADB_DEBUG + if (adb_debug) + printf("adb: ems_init timed out\n"); +#endif + return; + } + + /* Attempt to initialize Extended Mouse Protocol */ + buffer[2] = 4; /* make handler ID 4 */ + cmd = ADBLISTEN(adbaddr, 3); + if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd)) { +#ifdef ADB_DEBUG + if (adb_debug) + printf("adb: ems_init timed out\n"); +#endif + return; + } + + /* + * Check to see if successful, if not + * try to initialize it as other types + */ + cmd = ADBTALK(adbaddr, 3); + if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0 && + buffer[2] == ADBMS_EXTENDED) { + sc->handler_id = ADBMS_EXTENDED; + cmd = ADBTALK(adbaddr, 1); + if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd)) { +#ifdef ADB_DEBUG + if (adb_debug) + printf("adb: ems_init timed out\n"); +#endif + } else 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. + */ + cmd = ADBLISTEN(adbaddr, 1); + buffer[0]=2; + buffer[1]=0x00; + buffer[2]=0x81; + adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd); + + cmd = ADBLISTEN(adbaddr, 1); + buffer[0]=2; + buffer[1]=0x01; + buffer[2]=0x81; + adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd); + + cmd = ADBLISTEN(adbaddr, 1); + buffer[0]=2; + buffer[1]=0x02; + buffer[2]=0x81; + adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd); + + cmd = ADBLISTEN(adbaddr, 1); + buffer[0]=2; + buffer[1]=0x03; + buffer[2]=0x38; + adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd); + + 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 */ + cmd = ADBLISTEN(adbaddr, 3); + if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd)) { +#ifdef ADB_DEBUG + if (adb_debug) + printf("adb: ems_init timed out\n"); +#endif + return; + } + + /* + * Check to see if successful, if not + * try to initialize it as other types + */ + cmd = ADBTALK(adbaddr, 3); + if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0 + && buffer[2] == ADBMS_MSA3) { + sc->handler_id = ADBMS_MSA3; + /* Initialize as above */ + cmd = ADBLISTEN(adbaddr, 2); + /* listen 2 */ + buffer[0] = 3; + buffer[1] = 0x00; + /* Irrelevant, buffer has 0x77 */ + buffer[2] = 0x07; + /* + * enable 3 button mode = 0111b, + * speed = normal + */ + adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd); + 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(caddr_t buffer, caddr_t data_area, int adb_command) +{ + adb_event_t event; + struct ams_softc *sc; + int adbaddr; +#ifdef ADB_DEBUG + int i; + + if (adb_debug) + printf("adb: transaction completion\n"); +#endif + + adbaddr = ADB_CMDADDR(adb_command); + sc = (struct ams_softc *)data_area; + + if ((sc->handler_id == ADBMS_EXTENDED) && (sc->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 = sc->handler_id; + event.def_addr = sc->origaddr; + event.byte_count = buffer[0]; + memcpy(event.bytes, buffer + 1, event.byte_count); + +#ifdef ADB_DEBUG + if (adb_debug) { + printf("ams: 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, sc); +} + +/* + * Given a mouse ADB event, record the button settings, calculate the + * x- and y-axis motion, and handoff the event to the appropriate subsystem. + */ +void +ms_processevent(adb_event_t *event, struct ams_softc *sc) +{ + 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 = sc->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 (sc->sc_wsmousedev) + wsmouse_input(sc->sc_wsmousedev, new_event.u.m.buttons, + new_event.u.m.dx, -new_event.u.m.dy, 0, + WSMOUSE_INPUT_DELTA); +} + +int +ams_enable(void *v) +{ + return 0; +} + +int +ams_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + switch (cmd) { + case WSMOUSEIO_GTYPE: + *(u_int *)data = WSMOUSE_TYPE_ADB; + return (0); + } + + return -1; +} + +void +ams_disable(void *v) +{ +} diff --git a/sys/dev/adb/amsvar.h b/sys/dev/adb/amsvar.h new file mode 100644 index 00000000000..e121af61fcd --- /dev/null +++ b/sys/dev/adb/amsvar.h @@ -0,0 +1,64 @@ +/* $OpenBSD: amsvar.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */ +/* $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 _ADB_AMSVAR_H_ +#define _ADB_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 identifier */ + + 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 + +#endif /* _ADB_AMSVAR_H_ */ diff --git a/sys/dev/adb/files.adb b/sys/dev/adb/files.adb new file mode 100644 index 00000000000..7061d8ef0dc --- /dev/null +++ b/sys/dev/adb/files.adb @@ -0,0 +1,11 @@ +# $OpenBSD: files.adb,v 1.1 2006/01/18 23:21:17 miod Exp $ + +file dev/adb/adb_subr.c adb + +device akbd: wskbddev +attach akbd at adb +file dev/adb/akbd.c akbd needs-flag + +device ams: wsmousedev +attach ams at adb +file dev/adb/ams.c ams needs-flag diff --git a/sys/dev/adb/keyboard.h b/sys/dev/adb/keyboard.h new file mode 100644 index 00000000000..ae158f92b63 --- /dev/null +++ b/sys/dev/adb/keyboard.h @@ -0,0 +1,217 @@ +/* $OpenBSD: keyboard.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */ +/* $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][4]; +#else +unsigned char keyboard[128][4] = { + /* Scan code Normal Shifted Controlled XT */ + { /* 0x00, */ 'a', 'A', 0x01, 30 }, + { /* 0x01, */ 's', 'S', 0x13, 31 }, + { /* 0x02, */ 'd', 'D', 0x04, 32 }, + { /* 0x03, */ 'f', 'F', 0x06, 33 }, + { /* 0x04, */ 'h', 'H', 0x08, 35 }, + { /* 0x05, */ 'g', 'G', 0x07, 34 }, + { /* 0x06, */ 'z', 'Z', 0x1A, 44 }, + { /* 0x07, */ 'x', 'X', 0x18, 45 }, + { /* 0x08, */ 'c', 'C', 0x03, 46 }, + { /* 0x09, */ 'v', 'V', 0x16, 47 }, +#ifdef FIX_SV_X_KBDBUG + { /* 0x0A, */ 0x00, 0x00, 0x00, 41 }, +#else + { /* 0x0A, */ 0x00, 0x00, 0x00, 86 }, +#endif + { /* 0x0B, */ 'b', 'B', 0x02, 48 }, + { /* 0x0C, */ 'q', 'Q', 0x11, 16 }, + { /* 0x0D, */ 'w', 'W', 0x17, 17 }, + { /* 0x0E, */ 'e', 'E', 0x05, 18 }, + { /* 0x0F, */ 'r', 'R', 0x12, 19 }, + { /* 0x10, */ 'y', 'Y', 0x19, 21 }, + { /* 0x11, */ 't', 'T', 0x14, 20 }, + { /* 0x12, */ '1', '!', 0x00, 2 }, + { /* 0x13, */ '2', '@', 0x00, 3 }, + { /* 0x14, */ '3', '#', 0x00, 4 }, + { /* 0x15, */ '4', '$', 0x00, 5 }, + { /* 0x16, */ '6', '^', 0x1E, 7 }, + { /* 0x17, */ '5', '%', 0x00, 6 }, + { /* 0x18, */ '=', '+', 0x00, 13 }, + { /* 0x19, */ '9', '(', 0x00, 10 }, + { /* 0x1A, */ '7', '&', 0x00, 8 }, + { /* 0x1B, */ '-', '_', 0x1F, 12 }, + { /* 0x1C, */ '8', '*', 0x00, 9 }, + { /* 0x1D, */ '0', ')', 0x00, 11 }, + { /* 0x1E, */ ']', '}', 0x1D, 27 }, + { /* 0x1F, */ 'o', 'O', 0x0F, 24 }, + { /* 0x20, */ 'u', 'U', 0x15, 22 }, + { /* 0x21, */ '[', '{', 0x1B, 26 }, + { /* 0x22, */ 'i', 'I', 0x09, 23 }, + { /* 0x23, */ 'p', 'P', 0x10, 25 }, + { /* 0x24, */ 0x0D, 0x0D, 0x0D, 28 }, + { /* 0x25, */ 'l', 'L', 0x0C, 38 }, + { /* 0x26, */ 'j', 'J', 0x0A, 36 }, + { /* 0x27, */ '\'', '"', 0x00, 40 }, + { /* 0x28, */ 'k', 'K', 0x0B, 37 }, + { /* 0x29, */ ';', ':', 0x00, 39 }, + { /* 0x2A, */ '\\', '|', 0x1C, 43 }, + { /* 0x2B, */ ',', '<', 0x00, 51 }, + { /* 0x2C, */ '/', '?', 0x00, 53 }, + { /* 0x2D, */ 'n', 'N', 0x0E, 49 }, + { /* 0x2E, */ 'm', 'M', 0x0D, 50 }, + { /* 0x2F, */ '.', '>', 0x00, 52 }, + { /* 0x30, */ 0x09, 0x09, 0x09, 15 }, + { /* 0x31, */ ' ', ' ', 0x00, 57 }, +#ifdef FIX_SV_X_KBDBUG + { /* 0x32, */ '`', '~', 0x00, 86 }, +#else + { /* 0x32, */ '`', '~', 0x00, 41 }, +#endif + { /* 0x33, */ 0x7F, 0x7F, 0x7F, 211 }, /* Delete */ + { /* 0x34, */ 0x00, 0x00, 0x00, 105 }, /* MODE/KP_Enter */ + { /* 0x35, */ 0x1B, 0x1B, 0x1B, 1 }, + { /* 0x36, */ 0x00, 0x00, 0x00, 29 }, + { /* 0x37, */ 0x00, 0x00, 0x00, 219 }, + { /* 0x38, */ 0x00, 0x00, 0x00, 42 }, + { /* 0x39, */ 0x00, 0x00, 0x00, 58 }, + { /* 0x3A, */ 0x00, 0x00, 0x00, 56 }, /* L Alt */ + { /* 0x3B, */ 'h', 0x00, 0x00, 203 }, /* Left */ + { /* 0x3C, */ 'l', 0x00, 0x00, 205 }, /* Right */ + { /* 0x3D, */ 'j', 0x00, 0x00, 208 }, /* Down */ + { /* 0x3E, */ 'k', 0x00, 0x00, 200 }, /* Up */ + { /* 0x3F, */ 0x00, 0x00, 0x00, 0 }, /* Fn */ + { /* 0x40, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x41, */ '.', '.', 0x00, 83 }, + { /* 0x42, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x43, */ '*', '*', 0x00, 55 }, + { /* 0x44, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x45, */ '+', '+', 0x00, 78 }, + { /* 0x46, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x47, */ 0x00, 0x00, 0x00, 69 }, + { /* 0x48, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x49, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x4A, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x4B, */ '/', '/', 0x00, 181 }, + { /* 0x4C, */ 0x0D, 0x0D, 0x0D, 156 }, + { /* 0x4D, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x4E, */ '-', '-', 0x00, 74 }, + { /* 0x4F, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x50, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x51, */ '=', '=', 0x00, 118 }, + { /* 0x52, */ '0', '0', 0x00, 82 }, + { /* 0x53, */ '1', '1', 0x00, 79 }, + { /* 0x54, */ '2', '2', 0x00, 80 }, + { /* 0x55, */ '3', '3', 0x00, 81 }, + { /* 0x56, */ '4', '4', 0x00, 75 }, + { /* 0x57, */ '5', '5', 0x00, 76 }, + { /* 0x58, */ '6', '6', 0x00, 77 }, + { /* 0x59, */ '7', '7', 0x00, 71 }, + { /* 0x5A, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x5B, */ '8', '8', 0x00, 72 }, + { /* 0x5C, */ '9', '9', 0x00, 73 }, + { /* 0x5D, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x5E, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x5F, */ 0x00, 0x00, 0x00, 51 }, + { /* 0x60, */ 0x00, 0x00, 0x00, 63 }, /* F5 */ + { /* 0x61, */ 0x00, 0x00, 0x00, 64 }, /* F6 */ + { /* 0x62, */ 0x00, 0x00, 0x00, 65 }, /* F7 */ + { /* 0x63, */ 0x00, 0x00, 0x00, 61 }, /* F3 */ + { /* 0x64, */ 0x00, 0x00, 0x00, 66 }, /* F8 */ + { /* 0x65, */ 0x00, 0x00, 0x00, 67 }, /* F9 */ + { /* 0x66, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x67, */ 0x00, 0x00, 0x00, 87 }, /* F11 */ + { /* 0x68, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x69, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x6A, */ 0x00, 0x00, 0x00, 156 }, + { /* 0x6B, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x6C, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x6D, */ 0x00, 0x00, 0x00, 68 }, /* F10 */ + { /* 0x6E, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x6F, */ 0x00, 0x00, 0x00, 88 }, /* F12 */ + { /* 0x70, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x71, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x72, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x73, */ 0x00, 0x00, 0x00, 199 }, + { /* 0x74, */ 0x00, 0x00, 0x00, 201 }, + { /* 0x75, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x76, */ 0x00, 0x00, 0x00, 62 }, /* F4 */ + { /* 0x77, */ 0x00, 0x00, 0x00, 207 }, + { /* 0x78, */ 0x00, 0x00, 0x00, 60 }, /* F2 */ + { /* 0x79, */ 0x00, 0x00, 0x00, 209 }, + { /* 0x7A, */ 0x00, 0x00, 0x00, 59 }, /* F1 */ + { /* 0x7B, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x7C, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x7D, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x7E, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x7F, */ 0x00, 0x00, 0x00, 0 } /* pwr */ +}; +#endif /* KEYBOARD_ARRAY */ |