[BACK]Return to lms.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / i386 / isa

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

1.44.6.3! skrll       1: /*     $NetBSD: lms.c,v 1.44.6.2 2004/09/21 13:16:57 skrll Exp $       */
1.14      cgd         2:
1.1       andrew      3: /*-
1.35      mycroft     4:  * Copyright (c) 1993, 1994 Charles M. Hannum.
1.1       andrew      5:  * Copyright (c) 1992, 1993 Erik Forsberg.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  *
                     14:  * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
                     15:  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
                     16:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
                     17:  * NO EVENT SHALL I BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
                     18:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     19:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
                     20:  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
                     21:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
                     22:  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
                     23:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     24:  */
1.39      lukem      25:
                     26: #include <sys/cdefs.h>
1.44.6.3! skrll      27: __KERNEL_RCSID(0, "$NetBSD: lms.c,v 1.44.6.2 2004/09/21 13:16:57 skrll Exp $");
1.1       andrew     28:
1.7       mycroft    29: #include <sys/param.h>
                     30: #include <sys/systm.h>
                     31: #include <sys/ioctl.h>
1.8       mycroft    32: #include <sys/device.h>
1.7       mycroft    33:
1.23      thorpej    34: #include <machine/bus.h>
1.26      mycroft    35: #include <machine/intr.h>
1.1       andrew     36:
1.19      cgd        37: #include <dev/isa/isavar.h>
1.1       andrew     38:
1.37      drochner   39: #include <dev/wscons/wsconsio.h>
                     40: #include <dev/wscons/wsmousevar.h>
                     41:
1.8       mycroft    42: #define        LMS_DATA        0       /* offset for data port, read-only */
                     43: #define        LMS_SIGN        1       /* offset for signature port, read-write */
                     44: #define        LMS_INTR        2       /* offset for interrupt port, read-only */
                     45: #define        LMS_CNTRL       2       /* offset for control port, write-only */
                     46: #define        LMS_CONFIG      3       /* for configuration port, read-write */
                     47: #define        LMS_NPORTS      4
                     48:
                     49: struct lms_softc {             /* driver status information */
                     50:        struct device sc_dev;
1.19      cgd        51:        void *sc_ih;
1.8       mycroft    52:
1.30      thorpej    53:        bus_space_tag_t sc_iot;         /* bus i/o space identifier */
                     54:        bus_space_handle_t sc_ioh;      /* bus i/o handle */
1.23      thorpej    55:
1.37      drochner   56:        int sc_enabled; /* device is open */
                     57:        int oldbuttons; /* mouse button status */
                     58:
                     59:        struct device *sc_wsmousedev;
1.10      mycroft    60: };
1.1       andrew     61:
1.34      drochner   62: int lmsprobe __P((struct device *, struct cfdata *, void *));
1.16      mycroft    63: void lmsattach __P((struct device *, struct device *, void *));
1.19      cgd        64: int lmsintr __P((void *));
1.1       andrew     65:
1.44      thorpej    66: CFATTACH_DECL(lms, sizeof(struct lms_softc),
                     67:     lmsprobe, lmsattach, NULL, NULL);
1.22      thorpej    68:
1.37      drochner   69: int    lms_enable __P((void *));
1.44.6.3! skrll      70: int    lms_ioctl __P((void *, u_long, caddr_t, int, struct lwp *));
1.37      drochner   71: void   lms_disable __P((void *));
                     72:
                     73: const struct wsmouse_accessops lms_accessops = {
                     74:        lms_enable,
                     75:        lms_ioctl,
                     76:        lms_disable,
                     77: };
1.8       mycroft    78:
                     79: int
1.16      mycroft    80: lmsprobe(parent, match, aux)
                     81:        struct device *parent;
1.34      drochner   82:        struct cfdata *match;
                     83:        void *aux;
1.1       andrew     84: {
1.10      mycroft    85:        struct isa_attach_args *ia = aux;
1.30      thorpej    86:        bus_space_tag_t iot = ia->ia_iot;
                     87:        bus_space_handle_t ioh;
1.23      thorpej    88:        int rv;
1.40      thorpej    89:
                     90:        if (ia->ia_nio < 1)
                     91:                return (0);
                     92:        if (ia->ia_nirq < 1)
                     93:                return (0);
                     94:
                     95:        if (ISA_DIRECT_CONFIG(ia))
                     96:                return (0);
                     97:
1.31      thorpej    98:        /* Disallow wildcarded i/o base. */
1.44.6.1  skrll      99:        if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
1.40      thorpej   100:                return 0;
1.44.6.1  skrll     101:        if (ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ)
1.31      thorpej   102:                return 0;
                    103:
1.23      thorpej   104:        /* Map the i/o space. */
1.40      thorpej   105:        if (bus_space_map(iot, ia->ia_io[0].ir_addr, LMS_NPORTS, 0, &ioh))
1.23      thorpej   106:                return 0;
                    107:
                    108:        rv = 0;
1.1       andrew    109:
1.8       mycroft   110:        /* Configure and check for port present. */
1.30      thorpej   111:        bus_space_write_1(iot, ioh, LMS_CONFIG, 0x91);
1.9       mycroft   112:        delay(10);
1.30      thorpej   113:        bus_space_write_1(iot, ioh, LMS_SIGN, 0x0c);
1.9       mycroft   114:        delay(10);
1.30      thorpej   115:        if (bus_space_read_1(iot, ioh, LMS_SIGN) != 0x0c)
1.23      thorpej   116:                goto out;
1.30      thorpej   117:        bus_space_write_1(iot, ioh, LMS_SIGN, 0x50);
1.9       mycroft   118:        delay(10);
1.30      thorpej   119:        if (bus_space_read_1(iot, ioh, LMS_SIGN) != 0x50)
1.23      thorpej   120:                goto out;
1.1       andrew    121:
1.8       mycroft   122:        /* Disable interrupts. */
1.30      thorpej   123:        bus_space_write_1(iot, ioh, LMS_CNTRL, 0x10);
1.1       andrew    124:
1.23      thorpej   125:        rv = 1;
1.40      thorpej   126:        ia->ia_nio = 1;
                    127:        ia->ia_io[0].ir_size = LMS_NPORTS;
                    128:
                    129:        ia->ia_nirq = 1;
                    130:
                    131:        ia->ia_niomem = 0;
                    132:        ia->ia_ndrq = 0;
1.23      thorpej   133:
                    134: out:
1.30      thorpej   135:        bus_space_unmap(iot, ioh, LMS_NPORTS);
1.23      thorpej   136:        return rv;
1.1       andrew    137: }
                    138:
1.10      mycroft   139: void
                    140: lmsattach(parent, self, aux)
                    141:        struct device *parent, *self;
                    142:        void *aux;
1.1       andrew    143: {
1.10      mycroft   144:        struct lms_softc *sc = (void *)self;
                    145:        struct isa_attach_args *ia = aux;
1.32      mycroft   146:        bus_space_tag_t iot = ia->ia_iot;
                    147:        bus_space_handle_t ioh;
1.37      drochner  148:        struct wsmousedev_attach_args a;
1.11      mycroft   149:
1.29      christos  150:        printf("\n");
1.1       andrew    151:
1.40      thorpej   152:        if (bus_space_map(iot, ia->ia_io[0].ir_addr, LMS_NPORTS, 0, &ioh)) {
1.32      mycroft   153:                printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
                    154:                return;
                    155:        }
                    156:
1.8       mycroft   157:        /* Other initialization was done by lmsprobe. */
1.32      mycroft   158:        sc->sc_iot = iot;
                    159:        sc->sc_ioh = ioh;
1.37      drochner  160:        sc->sc_enabled = 0;
1.12      mycroft   161:
1.40      thorpej   162:        sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
                    163:            IST_PULSE, IPL_TTY, lmsintr, sc);
1.37      drochner  164:
                    165:        a.accessops = &lms_accessops;
                    166:        a.accesscookie = sc;
                    167:
                    168:        /*
                    169:         * Attach the wsmouse, saving a handle to it.
                    170:         * Note that we don't need to check this pointer against NULL
                    171:         * here or in psmintr, because if this fails lms_enable() will
                    172:         * never be called, so lmsintr() will never be called.
                    173:         */
                    174:        sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
1.1       andrew    175: }
                    176:
1.8       mycroft   177: int
1.37      drochner  178: lms_enable(v)
                    179:        void *v;
1.1       andrew    180: {
1.37      drochner  181:        struct lms_softc *sc = v;
1.1       andrew    182:
1.37      drochner  183:        if (sc->sc_enabled)
1.8       mycroft   184:                return EBUSY;
1.1       andrew    185:
1.37      drochner  186:        sc->sc_enabled = 1;
                    187:        sc->oldbuttons = 0;
1.1       andrew    188:
1.8       mycroft   189:        /* Enable interrupts. */
1.30      thorpej   190:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, LMS_CNTRL, 0);
1.1       andrew    191:
1.8       mycroft   192:        return 0;
1.1       andrew    193: }
                    194:
1.37      drochner  195: void
                    196: lms_disable(v)
                    197:        void *v;
1.1       andrew    198: {
1.37      drochner  199:        struct lms_softc *sc = v;
1.1       andrew    200:
1.8       mycroft   201:        /* Disable interrupts. */
1.30      thorpej   202:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, LMS_CNTRL, 0x10);
1.1       andrew    203:
1.37      drochner  204:        sc->sc_enabled = 0;
1.1       andrew    205: }
                    206:
1.8       mycroft   207: int
1.44.6.3! skrll     208: lms_ioctl(v, cmd, data, flag, l)
1.37      drochner  209:        void *v;
1.15      cgd       210:        u_long cmd;
1.37      drochner  211:        caddr_t data;
1.8       mycroft   212:        int flag;
1.44.6.3! skrll     213:        struct lwp *l;
1.1       andrew    214: {
1.37      drochner  215: #if 0
                    216:        struct lms_softc *sc = v;
                    217: #endif
1.1       andrew    218:
                    219:        switch (cmd) {
1.37      drochner  220:        case WSMOUSEIO_GTYPE:
                    221:                *(u_int *)data = WSMOUSE_TYPE_LMS;
                    222:                return (0);
1.8       mycroft   223:        }
1.41      atatat    224:        return (EPASSTHROUGH);
1.1       andrew    225: }
                    226:
1.8       mycroft   227: int
1.19      cgd       228: lmsintr(arg)
                    229:        void *arg;
1.1       andrew    230: {
1.19      cgd       231:        struct lms_softc *sc = arg;
1.30      thorpej   232:        bus_space_tag_t iot = sc->sc_iot;
                    233:        bus_space_handle_t ioh = sc->sc_ioh;
1.37      drochner  234:        u_char hi, lo;
                    235:        signed char dx, dy;
                    236:        u_int buttons;
                    237:        int changed;
1.8       mycroft   238:
1.37      drochner  239:        if (!sc->sc_enabled)
1.8       mycroft   240:                /* Interrupts are not expected. */
                    241:                return 0;
                    242:
1.30      thorpej   243:        bus_space_write_1(iot, ioh, LMS_CNTRL, 0xab);
                    244:        hi = bus_space_read_1(iot, ioh, LMS_DATA);
                    245:        bus_space_write_1(iot, ioh, LMS_CNTRL, 0x90);
                    246:        lo = bus_space_read_1(iot, ioh, LMS_DATA);
1.8       mycroft   247:        dx = ((hi & 0x0f) << 4) | (lo & 0x0f);
                    248:        /* Bounding at -127 avoids a bug in XFree86. */
1.3       mycroft   249:        dx = (dx == -128) ? -127 : dx;
                    250:
1.30      thorpej   251:        bus_space_write_1(iot, ioh, LMS_CNTRL, 0xf0);
                    252:        hi = bus_space_read_1(iot, ioh, LMS_DATA);
                    253:        bus_space_write_1(iot, ioh, LMS_CNTRL, 0xd0);
                    254:        lo = bus_space_read_1(iot, ioh, LMS_DATA);
1.8       mycroft   255:        dy = ((hi & 0x0f) << 4) | (lo & 0x0f);
1.1       andrew    256:        dy = (dy == -128) ? 127 : -dy;
1.3       mycroft   257:
1.30      thorpej   258:        bus_space_write_1(iot, ioh, LMS_CNTRL, 0);
1.8       mycroft   259:
1.37      drochner  260:        buttons = ((hi & 0x80) ? 0 : 0x1) |
                    261:                ((hi & 0x40) ? 0 : 0x2) |
                    262:                ((hi & 0x20) ? 0 : 0x4);
                    263:        changed = (buttons ^ sc->oldbuttons);
                    264:        sc->oldbuttons = buttons;
                    265:
                    266:        if (dx || dy || changed)
                    267:                wsmouse_input(sc->sc_wsmousedev,
1.38      takemura  268:                              buttons, dx, dy, 0, WSMOUSE_INPUT_DELTA);
1.8       mycroft   269:
1.12      mycroft   270:        return -1;
1.1       andrew    271: }

CVSweb <webmaster@jp.NetBSD.org>