[BACK]Return to mms.c CVS log [TXT][DIR] Up to [local] / sys / arch / i386 / isa

Annotation of sys/arch/i386/isa/mms.c, Revision 1.1.1.1

1.1       nbrk        1: /* $OpenBSD: mms.c,v 1.19 2007/04/10 22:37:17 miod Exp $ */
                      2: /*     $NetBSD: mms.c,v 1.35 2000/01/08 02:57:25 takemura Exp $        */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1993, 1994 Charles M. Hannum.
                      6:  * Copyright (c) 1992, 1993 Erik Forsberg.
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  *
                     15:  * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
                     16:  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
                     17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
                     18:  * NO EVENT SHALL I BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
                     19:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     20:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
                     21:  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
                     22:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
                     23:  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
                     24:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     25:  */
                     26:
                     27: #include <sys/param.h>
                     28: #include <sys/systm.h>
                     29: #include <sys/ioctl.h>
                     30: #include <sys/device.h>
                     31:
                     32: #include <machine/intr.h>
                     33: #include <machine/bus.h>
                     34:
                     35: #include <dev/isa/isavar.h>
                     36:
                     37: #include <dev/wscons/wsconsio.h>
                     38: #include <dev/wscons/wsmousevar.h>
                     39:
                     40: #define        MMS_ADDR        0       /* offset for register select */
                     41: #define        MMS_DATA        1       /* offset for InPort data */
                     42: #define        MMS_IDENT       2       /* offset for identification register */
                     43: #define        MMS_NPORTS      4
                     44:
                     45: struct mms_softc {             /* driver status information */
                     46:        struct device sc_dev;
                     47:        void *sc_ih;
                     48:
                     49:        bus_space_tag_t sc_iot;
                     50:        bus_space_handle_t sc_ioh;
                     51:
                     52:        int sc_enabled; /* device is open */
                     53:
                     54:        struct device *sc_wsmousedev;
                     55: };
                     56:
                     57: int mmsprobe(struct device *, void *, void *);
                     58: void mmsattach(struct device *, struct device *, void *);
                     59: int mmsintr(void *);
                     60:
                     61: struct cfattach mms_ca = {
                     62:        sizeof(struct mms_softc), mmsprobe, mmsattach
                     63: };
                     64:
                     65: int    mms_enable(void *);
                     66: int    mms_ioctl(void *, u_long, caddr_t, int, struct proc *);
                     67: void   mms_disable(void *);
                     68:
                     69: const struct wsmouse_accessops mms_accessops = {
                     70:        mms_enable,
                     71:        mms_ioctl,
                     72:        mms_disable,
                     73: };
                     74:
                     75: int
                     76: mmsprobe(struct device *parent, void *match, void *aux)
                     77: {
                     78:        struct isa_attach_args *ia = aux;
                     79:        bus_space_tag_t iot = ia->ia_iot;
                     80:        bus_space_handle_t ioh;
                     81:        int rv;
                     82:
                     83:        /* Disallow wildcarded i/o address. */
                     84:        if (ia->ia_iobase == IOBASEUNK)
                     85:                return 0;
                     86:
                     87:        /* Map the i/o space. */
                     88:        if (bus_space_map(iot, ia->ia_iobase, MMS_NPORTS, 0, &ioh))
                     89:                return 0;
                     90:
                     91:        rv = 0;
                     92:
                     93:        /* Read identification register to see if present */
                     94:        if (bus_space_read_1(iot, ioh, MMS_IDENT) != 0xde)
                     95:                goto out;
                     96:
                     97:        /* Seems it was there; reset. */
                     98:        bus_space_write_1(iot, ioh, MMS_ADDR, 0x87);
                     99:
                    100:        rv = 1;
                    101:        ia->ia_iosize = MMS_NPORTS;
                    102:        ia->ia_msize = 0;
                    103:
                    104: out:
                    105:        bus_space_unmap(iot, ioh, MMS_NPORTS);
                    106:        return rv;
                    107: }
                    108:
                    109: void
                    110: mmsattach(struct device *parent, struct device *self, void *aux)
                    111: {
                    112:        struct mms_softc *sc = (void *)self;
                    113:        struct isa_attach_args *ia = aux;
                    114:        bus_space_tag_t iot = ia->ia_iot;
                    115:        bus_space_handle_t ioh;
                    116:        struct wsmousedev_attach_args a;
                    117:
                    118:        printf("\n");
                    119:
                    120:        if (bus_space_map(iot, ia->ia_iobase, MMS_NPORTS, 0, &ioh)) {
                    121:                printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
                    122:                return;
                    123:        }
                    124:
                    125:        /* Other initialization was done by mmsprobe. */
                    126:        sc->sc_iot = iot;
                    127:        sc->sc_ioh = ioh;
                    128:        sc->sc_enabled = 0;
                    129:
                    130:        sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_PULSE,
                    131:            IPL_TTY, mmsintr, sc, sc->sc_dev.dv_xname);
                    132:
                    133:        a.accessops = &mms_accessops;
                    134:        a.accesscookie = sc;
                    135:
                    136:        /*
                    137:         * Attach the wsmouse, saving a handle to it.
                    138:         * Note that we don't need to check this pointer against NULL
                    139:         * here or in psmintr, because if this fails lms_enable() will
                    140:         * never be called, so lmsintr() will never be called.
                    141:         */
                    142:        sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
                    143: }
                    144:
                    145: int
                    146: mms_enable(void *v)
                    147: {
                    148:        struct mms_softc *sc = v;
                    149:
                    150:        if (sc->sc_enabled)
                    151:                return EBUSY;
                    152:
                    153:        sc->sc_enabled = 1;
                    154:
                    155:        /* Enable interrupts. */
                    156:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, MMS_ADDR, 0x07);
                    157:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, MMS_DATA, 0x09);
                    158:
                    159:        return 0;
                    160: }
                    161:
                    162: void
                    163: mms_disable(void *v)
                    164: {
                    165:        struct mms_softc *sc = v;
                    166:
                    167:        /* Disable interrupts. */
                    168:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, MMS_ADDR, 0x87);
                    169:
                    170:        sc->sc_enabled = 0;
                    171: }
                    172:
                    173: int
                    174: mms_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
                    175: {
                    176: #if 0
                    177:        struct mms_softc *sc = v;
                    178: #endif
                    179:
                    180:        switch (cmd) {
                    181:        case WSMOUSEIO_GTYPE:
                    182:                *(u_int *)data = WSMOUSE_TYPE_MMS;
                    183:                return (0);
                    184:        }
                    185:        return (-1);
                    186: }
                    187:
                    188: int
                    189: mmsintr(void *arg)
                    190: {
                    191:        struct mms_softc *sc = arg;
                    192:        bus_space_tag_t iot = sc->sc_iot;
                    193:        bus_space_handle_t ioh = sc->sc_ioh;
                    194:        u_char status;
                    195:        signed char dx, dy;
                    196:        u_int buttons;
                    197:        int changed;
                    198:
                    199:        if (!sc->sc_enabled)
                    200:                /* Interrupts are not expected. */
                    201:                return 0;
                    202:
                    203:        /* Freeze InPort registers (disabling interrupts). */
                    204:        bus_space_write_1(iot, ioh, MMS_ADDR, 0x07);
                    205:        bus_space_write_1(iot, ioh, MMS_DATA, 0x29);
                    206:
                    207:        bus_space_write_1(iot, ioh, MMS_ADDR, 0x00);
                    208:        status = bus_space_read_1(iot, ioh, MMS_DATA);
                    209:
                    210:        if (status & 0x40) {
                    211:                bus_space_write_1(iot, ioh, MMS_ADDR, 1);
                    212:                dx = bus_space_read_1(iot, ioh, MMS_DATA);
                    213:                /* Bounding at -127 avoids a bug in XFree86. */
                    214:                dx = (dx == -128) ? -127 : dx;
                    215:
                    216:                bus_space_write_1(iot, ioh, MMS_ADDR, 2);
                    217:                dy = bus_space_read_1(iot, ioh, MMS_DATA);
                    218:                dy = (dy == -128) ? 127 : -dy;
                    219:        } else
                    220:                dx = dy = 0;
                    221:
                    222:        /* Unfreeze InPort registers (reenabling interrupts). */
                    223:        bus_space_write_1(iot, ioh, MMS_ADDR, 0x07);
                    224:        bus_space_write_1(iot, ioh, MMS_DATA, 0x09);
                    225:
                    226:        buttons = ((status & 0x04) ? 0x1 : 0) |
                    227:                ((status & 0x02) ? 0x2 : 0) |
                    228:                ((status & 0x01) ? 0x4 : 0);
                    229:        changed = status & 0x38;
                    230:
                    231:        if (dx || dy || changed)
                    232:                wsmouse_input(sc->sc_wsmousedev,
                    233:                              buttons, dx, dy, 0, 0, WSMOUSE_INPUT_DELTA);
                    234:
                    235:        return -1;
                    236: }
                    237:
                    238: struct cfdriver mms_cd = {
                    239:        NULL, "mms", DV_DULL
                    240: };

CVSweb