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

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

1.1       nbrk        1: /*     $OpenBSD: lms.c,v 1.20 2007/04/10 22:37:17 miod Exp $   */
                      2: /*     $NetBSD: lms.c,v 1.38 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/bus.h>
                     33: #include <machine/intr.h>
                     34:
                     35: #include <dev/isa/isavar.h>
                     36:
                     37: #include <dev/wscons/wsconsio.h>
                     38: #include <dev/wscons/wsmousevar.h>
                     39:
                     40: #define        LMS_DATA        0       /* offset for data port, read-only */
                     41: #define        LMS_SIGN        1       /* offset for signature port, read-write */
                     42: #define        LMS_INTR        2       /* offset for interrupt port, read-only */
                     43: #define        LMS_CNTRL       2       /* offset for control port, write-only */
                     44: #define        LMS_CONFIG      3       /* for configuration port, read-write */
                     45: #define        LMS_NPORTS      4
                     46:
                     47: struct lms_softc {             /* driver status information */
                     48:        struct device sc_dev;
                     49:        void *sc_ih;
                     50:
                     51:        bus_space_tag_t sc_iot;         /* bus i/o space identifier */
                     52:        bus_space_handle_t sc_ioh;      /* bus i/o handle */
                     53:
                     54:        int sc_enabled; /* device is open */
                     55:        int oldbuttons; /* mouse button status */
                     56:
                     57:        struct device *sc_wsmousedev;
                     58: };
                     59:
                     60: int lmsprobe(struct device *, void *, void *);
                     61: void lmsattach(struct device *, struct device *, void *);
                     62: int lmsintr(void *);
                     63:
                     64: struct cfattach lms_ca = {
                     65:        sizeof(struct lms_softc), lmsprobe, lmsattach
                     66: };
                     67:
                     68: int    lms_enable(void *);
                     69: int    lms_ioctl(void *, u_long, caddr_t, int, struct proc *);
                     70: void   lms_disable(void *);
                     71:
                     72: const struct wsmouse_accessops lms_accessops = {
                     73:        lms_enable,
                     74:        lms_ioctl,
                     75:        lms_disable,
                     76: };
                     77:
                     78: int
                     79: lmsprobe(struct device *parent, void *match, void *aux)
                     80: {
                     81:        struct isa_attach_args *ia = aux;
                     82:        bus_space_tag_t iot = ia->ia_iot;
                     83:        bus_space_handle_t ioh;
                     84:        int rv;
                     85:
                     86:        /* Disallow wildcarded i/o base. */
                     87:        if (ia->ia_iobase == IOBASEUNK)
                     88:                return 0;
                     89:
                     90:        /* Map the i/o space. */
                     91:        if (bus_space_map(iot, ia->ia_iobase, LMS_NPORTS, 0, &ioh))
                     92:                return 0;
                     93:
                     94:        rv = 0;
                     95:
                     96:        /* Configure and check for port present. */
                     97:        bus_space_write_1(iot, ioh, LMS_CONFIG, 0x91);
                     98:        delay(10);
                     99:        bus_space_write_1(iot, ioh, LMS_SIGN, 0x0c);
                    100:        delay(10);
                    101:        if (bus_space_read_1(iot, ioh, LMS_SIGN) != 0x0c)
                    102:                goto out;
                    103:        bus_space_write_1(iot, ioh, LMS_SIGN, 0x50);
                    104:        delay(10);
                    105:        if (bus_space_read_1(iot, ioh, LMS_SIGN) != 0x50)
                    106:                goto out;
                    107:
                    108:        /* Disable interrupts. */
                    109:        bus_space_write_1(iot, ioh, LMS_CNTRL, 0x10);
                    110:
                    111:        rv = 1;
                    112:        ia->ia_iosize = LMS_NPORTS;
                    113:        ia->ia_msize = 0;
                    114:
                    115: out:
                    116:        bus_space_unmap(iot, ioh, LMS_NPORTS);
                    117:        return rv;
                    118: }
                    119:
                    120: void
                    121: lmsattach(struct device *parent, struct device *self, void *aux)
                    122: {
                    123:        struct lms_softc *sc = (void *)self;
                    124:        struct isa_attach_args *ia = aux;
                    125:        bus_space_tag_t iot = ia->ia_iot;
                    126:        bus_space_handle_t ioh;
                    127:        struct wsmousedev_attach_args a;
                    128:
                    129:        printf("\n");
                    130:
                    131:        if (bus_space_map(iot, ia->ia_iobase, LMS_NPORTS, 0, &ioh)) {
                    132:                printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
                    133:                return;
                    134:        }
                    135:
                    136:        /* Other initialization was done by lmsprobe. */
                    137:        sc->sc_iot = iot;
                    138:        sc->sc_ioh = ioh;
                    139:        sc->sc_enabled = 0;
                    140:
                    141:        sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_PULSE,
                    142:            IPL_TTY, lmsintr, sc, sc->sc_dev.dv_xname);
                    143:
                    144:        a.accessops = &lms_accessops;
                    145:        a.accesscookie = sc;
                    146:
                    147:        /*
                    148:         * Attach the wsmouse, saving a handle to it.
                    149:         * Note that we don't need to check this pointer against NULL
                    150:         * here or in psmintr, because if this fails lms_enable() will
                    151:         * never be called, so lmsintr() will never be called.
                    152:         */
                    153:        sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
                    154: }
                    155:
                    156: int
                    157: lms_enable(void *v)
                    158: {
                    159:        struct lms_softc *sc = v;
                    160:
                    161:        if (sc->sc_enabled)
                    162:                return EBUSY;
                    163:
                    164:        sc->sc_enabled = 1;
                    165:        sc->oldbuttons = 0;
                    166:
                    167:        /* Enable interrupts. */
                    168:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, LMS_CNTRL, 0);
                    169:
                    170:        return 0;
                    171: }
                    172:
                    173: void
                    174: lms_disable(void *v)
                    175: {
                    176:        struct lms_softc *sc = v;
                    177:
                    178:        /* Disable interrupts. */
                    179:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, LMS_CNTRL, 0x10);
                    180:
                    181:        sc->sc_enabled = 0;
                    182: }
                    183:
                    184: int
                    185: lms_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
                    186: {
                    187: #if 0
                    188:        struct lms_softc *sc = v;
                    189: #endif
                    190:
                    191:        switch (cmd) {
                    192:        case WSMOUSEIO_GTYPE:
                    193:                *(u_int *)data = WSMOUSE_TYPE_LMS;
                    194:                return (0);
                    195:        }
                    196:        return (-1);
                    197: }
                    198:
                    199: int
                    200: lmsintr(void *arg)
                    201: {
                    202:        struct lms_softc *sc = arg;
                    203:        bus_space_tag_t iot = sc->sc_iot;
                    204:        bus_space_handle_t ioh = sc->sc_ioh;
                    205:        u_char hi, lo;
                    206:        signed char dx, dy;
                    207:        u_int buttons;
                    208:        int changed;
                    209:
                    210:        if (!sc->sc_enabled)
                    211:                /* Interrupts are not expected. */
                    212:                return 0;
                    213:
                    214:        bus_space_write_1(iot, ioh, LMS_CNTRL, 0xab);
                    215:        hi = bus_space_read_1(iot, ioh, LMS_DATA);
                    216:        bus_space_write_1(iot, ioh, LMS_CNTRL, 0x90);
                    217:        lo = bus_space_read_1(iot, ioh, LMS_DATA);
                    218:        dx = ((hi & 0x0f) << 4) | (lo & 0x0f);
                    219:        /* Bounding at -127 avoids a bug in XFree86. */
                    220:        dx = (dx == -128) ? -127 : dx;
                    221:
                    222:        bus_space_write_1(iot, ioh, LMS_CNTRL, 0xf0);
                    223:        hi = bus_space_read_1(iot, ioh, LMS_DATA);
                    224:        bus_space_write_1(iot, ioh, LMS_CNTRL, 0xd0);
                    225:        lo = bus_space_read_1(iot, ioh, LMS_DATA);
                    226:        dy = ((hi & 0x0f) << 4) | (lo & 0x0f);
                    227:        dy = (dy == -128) ? 127 : -dy;
                    228:
                    229:        bus_space_write_1(iot, ioh, LMS_CNTRL, 0);
                    230:
                    231:        buttons = ((hi & 0x80) ? 0 : 0x1) |
                    232:                ((hi & 0x40) ? 0 : 0x2) |
                    233:                ((hi & 0x20) ? 0 : 0x4);
                    234:        changed = (buttons ^ sc->oldbuttons);
                    235:        sc->oldbuttons = buttons;
                    236:
                    237:        if (dx || dy || changed)
                    238:                wsmouse_input(sc->sc_wsmousedev,
                    239:                              buttons, dx, dy, 0, 0, WSMOUSE_INPUT_DELTA);
                    240:
                    241:        return -1;
                    242: }
                    243:
                    244: struct cfdriver lms_cd = {
                    245:        NULL, "lms", DV_DULL
                    246: };

CVSweb