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