[BACK]Return to hilms.c CVS log [TXT][DIR] Up to [local] / sys / dev / hil

Annotation of sys/dev/hil/hilms.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: hilms.c,v 1.5 2007/04/10 22:37:17 miod Exp $  */
        !             2: /*
        !             3:  * Copyright (c) 2003, Miodrag Vallat.
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  * 1. Redistributions of source code must retain the above copyright
        !            10:  *    notice, this list of conditions and the following disclaimer.
        !            11:  * 2. Redistributions in binary form must reproduce the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer in the
        !            13:  *    documentation and/or other materials provided with the distribution.
        !            14:  *
        !            15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            16:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        !            18:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
        !            19:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            20:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            21:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            22:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            23:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
        !            24:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            25:  * POSSIBILITY OF SUCH DAMAGE.
        !            26:  *
        !            27:  */
        !            28:
        !            29: #include <sys/param.h>
        !            30: #include <sys/systm.h>
        !            31: #include <sys/device.h>
        !            32: #include <sys/ioctl.h>
        !            33:
        !            34: #include <machine/autoconf.h>
        !            35: #include <machine/bus.h>
        !            36: #include <machine/cpu.h>
        !            37:
        !            38: #include <dev/hil/hilreg.h>
        !            39: #include <dev/hil/hilvar.h>
        !            40: #include <dev/hil/hildevs.h>
        !            41:
        !            42: #include <dev/wscons/wsconsio.h>
        !            43: #include <dev/wscons/wsmousevar.h>
        !            44:
        !            45: struct hilms_softc {
        !            46:        struct hildev_softc sc_hildev;
        !            47:
        !            48:        int             sc_features;
        !            49:        u_int           sc_buttons;
        !            50:        u_int           sc_axes;
        !            51:        int             sc_enabled;
        !            52:        int             sc_buttonstate;
        !            53:
        !            54:        struct device   *sc_wsmousedev;
        !            55: };
        !            56:
        !            57: int    hilmsprobe(struct device *, void *, void *);
        !            58: void   hilmsattach(struct device *, struct device *, void *);
        !            59: int    hilmsdetach(struct device *, int);
        !            60:
        !            61: struct cfdriver hilms_cd = {
        !            62:        NULL, "hilms", DV_DULL
        !            63: };
        !            64:
        !            65: struct cfattach hilms_ca = {
        !            66:        sizeof(struct hilms_softc), hilmsprobe, hilmsattach, hilmsdetach,
        !            67: };
        !            68:
        !            69: int    hilms_enable(void *);
        !            70: int    hilms_ioctl(void *, u_long, caddr_t, int, struct proc *);
        !            71: void   hilms_disable(void *);
        !            72:
        !            73: const struct wsmouse_accessops hilms_accessops = {
        !            74:        hilms_enable,
        !            75:        hilms_ioctl,
        !            76:        hilms_disable,
        !            77: };
        !            78:
        !            79: void   hilms_callback(struct hildev_softc *, u_int, u_int8_t *);
        !            80:
        !            81: int
        !            82: hilmsprobe(struct device *parent, void *match, void *aux)
        !            83: {
        !            84:        struct hil_attach_args *ha = aux;
        !            85:
        !            86:        if (ha->ha_type != HIL_DEVICE_MOUSE)
        !            87:                return (0);
        !            88:
        !            89:        /*
        !            90:         * Reject anything that has only buttons - they are handled as
        !            91:         * keyboards, really.
        !            92:         */
        !            93:        if (ha->ha_infolen > 1 && (ha->ha_info[1] & HIL_AXMASK) == 0)
        !            94:                return (0);
        !            95:
        !            96:        return (1);
        !            97: }
        !            98:
        !            99: void
        !           100: hilmsattach(struct device *parent, struct device *self, void *aux)
        !           101: {
        !           102:        struct hilms_softc *sc = (void *)self;
        !           103:        struct hil_attach_args *ha = aux;
        !           104:        struct wsmousedev_attach_args a;
        !           105:        int iob, rx, ry;
        !           106:
        !           107:        sc->hd_code = ha->ha_code;
        !           108:        sc->hd_type = ha->ha_type;
        !           109:        sc->hd_infolen = ha->ha_infolen;
        !           110:        bcopy(ha->ha_info, sc->hd_info, ha->ha_infolen);
        !           111:        sc->hd_fn = hilms_callback;
        !           112:
        !           113:        /*
        !           114:         * Interpret the identification bytes, if any
        !           115:         */
        !           116:        rx = ry = 0;
        !           117:        if (ha->ha_infolen > 1) {
        !           118:                sc->sc_features = ha->ha_info[1];
        !           119:                sc->sc_axes = sc->sc_features & HIL_AXMASK;
        !           120:
        !           121:                if (sc->sc_features & HIL_IOB) {
        !           122:                        /* skip resolution bytes */
        !           123:                        iob = 4;
        !           124:                        if (sc->sc_features & HIL_ABSOLUTE) {
        !           125:                                /* skip ranges */
        !           126:                                rx = ha->ha_info[4] | (ha->ha_info[5] << 8);
        !           127:                                if (sc->sc_axes > 1)
        !           128:                                        ry = ha->ha_info[6] |
        !           129:                                            (ha->ha_info[7] << 8);
        !           130:                                iob += 2 * sc->sc_axes;
        !           131:                        }
        !           132:
        !           133:                        if (iob >= ha->ha_infolen) {
        !           134:                                sc->sc_features &= ~(HIL_IOB | HILIOB_PIO);
        !           135:                        } else {
        !           136:                                iob = ha->ha_info[iob];
        !           137:                                sc->sc_buttons = iob & HILIOB_BMASK;
        !           138:                                sc->sc_features |= (iob & HILIOB_PIO);
        !           139:                        }
        !           140:                }
        !           141:        }
        !           142:
        !           143:        printf(", %d axes", sc->sc_axes);
        !           144:        if (sc->sc_buttons == 1)
        !           145:                printf(", 1 button");
        !           146:        else if (sc->sc_buttons > 1)
        !           147:                printf(", %d buttons", sc->sc_buttons);
        !           148:        if (sc->sc_features & HILIOB_PIO)
        !           149:                printf(", pressure sensor");
        !           150:        if (sc->sc_features & HIL_ABSOLUTE) {
        !           151:                printf ("\n%s: %d", self->dv_xname, rx);
        !           152:                if (ry != 0)
        !           153:                        printf("x%d", ry);
        !           154:                else
        !           155:                        printf(" linear");
        !           156:                printf(" fixed area");
        !           157:        }
        !           158:
        !           159:        printf("\n");
        !           160:
        !           161:        sc->sc_enabled = 0;
        !           162:
        !           163:        a.accessops = &hilms_accessops;
        !           164:        a.accesscookie = sc;
        !           165:
        !           166:        sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
        !           167: }
        !           168:
        !           169: int
        !           170: hilmsdetach(struct device *self, int flags)
        !           171: {
        !           172:        struct hilms_softc *sc = (void *)self;
        !           173:
        !           174:        if (sc->sc_wsmousedev != NULL)
        !           175:                return config_detach(sc->sc_wsmousedev, flags);
        !           176:
        !           177:        return (0);
        !           178: }
        !           179:
        !           180: int
        !           181: hilms_enable(void *v)
        !           182: {
        !           183:        struct hilms_softc *sc = v;
        !           184:
        !           185:        if (sc->sc_enabled)
        !           186:                return EBUSY;
        !           187:
        !           188:        sc->sc_enabled = 1;
        !           189:        sc->sc_buttonstate = 0;
        !           190:
        !           191:        return (0);
        !           192: }
        !           193:
        !           194: void
        !           195: hilms_disable(void *v)
        !           196: {
        !           197:        struct hilms_softc *sc = v;
        !           198:
        !           199:        sc->sc_enabled = 0;
        !           200: }
        !           201:
        !           202: int
        !           203: hilms_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
        !           204: {
        !           205: #if 0
        !           206:        struct hilms_softc *sc = v;
        !           207: #endif
        !           208:
        !           209:        switch (cmd) {
        !           210:        case WSMOUSEIO_GTYPE:
        !           211:                *(int *)data = WSMOUSE_TYPE_HIL;
        !           212:                return 0;
        !           213:        }
        !           214:
        !           215:        return -1;
        !           216: }
        !           217:
        !           218: void
        !           219: hilms_callback(struct hildev_softc *dev, u_int buflen, u_int8_t *buf)
        !           220: {
        !           221:        struct hilms_softc *sc = (struct hilms_softc *)dev;
        !           222:        int type, flags;
        !           223:        int dx, dy, dz, button;
        !           224: #ifdef DIAGNOSTIC
        !           225:        int minlen;
        !           226: #endif
        !           227:
        !           228:        /*
        !           229:         * Ignore packet if we don't need it
        !           230:         */
        !           231:        if (sc->sc_enabled == 0)
        !           232:                return;
        !           233:
        !           234:        type = *buf++;
        !           235:
        !           236: #ifdef DIAGNOSTIC
        !           237:        /*
        !           238:         * Check that the packet contains all the expected data,
        !           239:         * ignore it if too short.
        !           240:         */
        !           241:        minlen = 1;
        !           242:        if (type & HIL_MOUSEMOTION) {
        !           243:                minlen += sc->sc_axes <<
        !           244:                    (sc->sc_features & HIL_16_BITS) ? 1 : 0;
        !           245:        }
        !           246:        if (type & HIL_MOUSEBUTTON)
        !           247:                minlen++;
        !           248:
        !           249:        if (minlen > buflen)
        !           250:                return;
        !           251: #endif
        !           252:
        !           253:        /*
        !           254:         * The packet can contain both a mouse motion and a button event.
        !           255:         * In this case, the motion data comes first.
        !           256:         */
        !           257:
        !           258:        if (type & HIL_MOUSEMOTION) {
        !           259:                flags = sc->sc_features & HIL_ABSOLUTE ?
        !           260:                    WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y |
        !           261:                    WSMOUSE_INPUT_ABSOLUTE_Z : WSMOUSE_INPUT_DELTA;
        !           262:                if (sc->sc_features & HIL_16_BITS) {
        !           263:                        dx = *buf++;
        !           264:                        dx |= (*buf++) << 8;
        !           265:                        if (!(sc->sc_features & HIL_ABSOLUTE))
        !           266:                                dx = (int16_t)dx;
        !           267:                } else {
        !           268:                        dx = *buf++;
        !           269:                        if (!(sc->sc_features & HIL_ABSOLUTE))
        !           270:                                dx = (int8_t)dx;
        !           271:                }
        !           272:                if (sc->sc_axes > 1) {
        !           273:                        if (sc->sc_features & HIL_16_BITS) {
        !           274:                                dy = *buf++;
        !           275:                                dy |= (*buf++) << 8;
        !           276:                                if (!(sc->sc_features & HIL_ABSOLUTE))
        !           277:                                        dy = (int16_t)dy;
        !           278:                        } else {
        !           279:                                dy = *buf++;
        !           280:                                if (!(sc->sc_features & HIL_ABSOLUTE))
        !           281:                                        dy = (int8_t)dy;
        !           282:                        }
        !           283:                        if (sc->sc_axes > 2) {
        !           284:                                if (sc->sc_features & HIL_16_BITS) {
        !           285:                                        dz = *buf++;
        !           286:                                        dz |= (*buf++) << 8;
        !           287:                                        if (!(sc->sc_features & HIL_ABSOLUTE))
        !           288:                                                dz = (int16_t)dz;
        !           289:                                } else {
        !           290:                                        dz = *buf++;
        !           291:                                        if (!(sc->sc_features & HIL_ABSOLUTE))
        !           292:                                                dz = (int8_t)dz;
        !           293:                                }
        !           294:                        } else
        !           295:                                dz = 0;
        !           296:                } else
        !           297:                        dy = dz = 0;
        !           298:
        !           299:                /*
        !           300:                 * Correct Y direction for button boxes.
        !           301:                 */
        !           302:                if ((sc->sc_features & HIL_ABSOLUTE) == 0 &&
        !           303:                    sc->sc_buttons == 0)
        !           304:                        dy = -dy;
        !           305:        } else
        !           306:                dx = dy = dz = flags = 0;
        !           307:
        !           308:        if (type & HIL_MOUSEBUTTON) {
        !           309:                button = *buf;
        !           310:                /*
        !           311:                 * The pressure sensor is very primitive and only has
        !           312:                 * a boolean behaviour, as an extra mouse button, which is
        !           313:                 * down if there is pressure or the pen is near the tablet,
        !           314:                 * and up if there is no pressure or the pen is far from the
        !           315:                 * tablet - at least for Tablet id 0x94, P/N 46088B
        !           316:                 *
        !           317:                 * The corresponding codes are 0x8f and 0x8e. Convert them
        !           318:                 * to a pseudo fourth button - even if the tablet never
        !           319:                 * has three buttons.
        !           320:                 */
        !           321:                button = (button - 0x80) >> 1;
        !           322:                if (button > 4)
        !           323:                        button = 4;
        !           324:
        !           325:                if (*buf & 1) {
        !           326:                        /* Button released, or no pressure */
        !           327:                        sc->sc_buttonstate &= ~(1 << button);
        !           328:                } else {
        !           329:                        /* Button pressed, or pressure */
        !           330:                        sc->sc_buttonstate |= (1 << button);
        !           331:                }
        !           332:                /* buf++; */
        !           333:        }
        !           334:
        !           335:        if (sc->sc_wsmousedev != NULL)
        !           336:                wsmouse_input(sc->sc_wsmousedev,
        !           337:                    sc->sc_buttonstate, dx, dy, dz, 0, flags);
        !           338: }

CVSweb