1 1.22 skrll /* $NetBSD: qms.c,v 1.22 2022/09/27 06:36:42 skrll Exp $ */ 2 1.1 reinoud 3 1.7 bjh21 /*- 4 1.7 bjh21 * Copyright (c) 2001 Reinoud Zandijk 5 1.7 bjh21 * All rights reserved. 6 1.7 bjh21 * 7 1.7 bjh21 * This code is derived from software contributed to The NetBSD Foundation 8 1.7 bjh21 * by Reinoud Zandijk 9 1.1 reinoud * 10 1.1 reinoud * Redistribution and use in source and binary forms, with or without 11 1.1 reinoud * modification, are permitted provided that the following conditions 12 1.1 reinoud * are met: 13 1.1 reinoud * 1. Redistributions of source code must retain the above copyright 14 1.1 reinoud * notice, this list of conditions and the following disclaimer. 15 1.1 reinoud * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 reinoud * notice, this list of conditions and the following disclaimer in the 17 1.1 reinoud * documentation and/or other materials provided with the distribution. 18 1.1 reinoud * 19 1.7 bjh21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.7 bjh21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.7 bjh21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.7 bjh21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.7 bjh21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.7 bjh21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.7 bjh21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.7 bjh21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.7 bjh21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.7 bjh21 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.7 bjh21 * POSSIBILITY OF SUCH DAMAGE. 30 1.1 reinoud */ 31 1.1 reinoud /* 32 1.7 bjh21 * Quadrature mouse driver for the wscons as used in the IOMD 33 1.1 reinoud */ 34 1.5 lukem 35 1.7 bjh21 #include <sys/param.h> 36 1.7 bjh21 37 1.22 skrll __KERNEL_RCSID(0, "$NetBSD: qms.c,v 1.22 2022/09/27 06:36:42 skrll Exp $"); 38 1.1 reinoud 39 1.7 bjh21 #include <sys/callout.h> 40 1.7 bjh21 #include <sys/device.h> 41 1.7 bjh21 #include <sys/errno.h> 42 1.1 reinoud #include <sys/ioctl.h> 43 1.7 bjh21 #include <sys/kernel.h> 44 1.7 bjh21 #include <sys/proc.h> 45 1.1 reinoud #include <sys/tty.h> 46 1.1 reinoud #include <sys/types.h> 47 1.7 bjh21 #include <sys/syslog.h> 48 1.7 bjh21 #include <sys/systm.h> 49 1.7 bjh21 #include <sys/select.h> 50 1.1 reinoud 51 1.16 dyoung #include <sys/bus.h> 52 1.7 bjh21 #include <machine/intr.h> 53 1.1 reinoud 54 1.7 bjh21 #include <arm/iomd/iomdvar.h> 55 1.1 reinoud 56 1.7 bjh21 #include <dev/wscons/wsconsio.h> 57 1.7 bjh21 #include <dev/wscons/wsmousevar.h> 58 1.1 reinoud 59 1.7 bjh21 struct qms_softc { 60 1.18 skrll device_t sc_dev; 61 1.18 skrll device_t sc_wsmousedev; 62 1.1 reinoud 63 1.7 bjh21 bus_space_tag_t sc_iot; /* bus tag */ 64 1.7 bjh21 bus_space_handle_t sc_ioh; /* bus handle for XY */ 65 1.7 bjh21 bus_space_handle_t sc_butioh; /* bus handle for buttons */ 66 1.2 gehenna 67 1.7 bjh21 struct callout sc_callout; 68 1.2 gehenna 69 1.17 skrll uint16_t lastx; 70 1.17 skrll uint16_t lasty; 71 1.7 bjh21 int lastb; 72 1.2 gehenna }; 73 1.1 reinoud 74 1.1 reinoud /* Offsets of hardware registers */ 75 1.7 bjh21 #define QMS_MOUSEX 0 /* 16 bits X register */ 76 1.7 bjh21 #define QMS_MOUSEY 1 /* 16 bits Y register */ 77 1.7 bjh21 #define QMS_BUTTONS 0 /* mouse buttons in bits 4,5,6 */ 78 1.7 bjh21 79 1.18 skrll static int qms_match(device_t , cfdata_t , void *); 80 1.18 skrll static void qms_attach(device_t , device_t , void *); 81 1.7 bjh21 82 1.7 bjh21 static int qms_enable(void *); 83 1.11 christos static int qms_ioctl(void *, u_long, void *, int, struct lwp *); 84 1.7 bjh21 static void qms_disable(void *cookie); 85 1.7 bjh21 static void qms_intr(void *arg); 86 1.1 reinoud 87 1.18 skrll CFATTACH_DECL_NEW(qms, sizeof(struct qms_softc), 88 1.7 bjh21 qms_match, qms_attach, NULL, NULL); 89 1.1 reinoud 90 1.7 bjh21 static struct wsmouse_accessops qms_accessops = { 91 1.7 bjh21 qms_enable, qms_ioctl, qms_disable 92 1.7 bjh21 }; 93 1.1 reinoud 94 1.1 reinoud 95 1.7 bjh21 static int 96 1.18 skrll qms_match(device_t parent, cfdata_t cf, void *aux) 97 1.1 reinoud { 98 1.7 bjh21 struct qms_attach_args *qa = aux; 99 1.1 reinoud 100 1.7 bjh21 if (strcmp(qa->qa_name, "qms") == 0) 101 1.9 bjh21 return 1; 102 1.1 reinoud 103 1.9 bjh21 return 0; 104 1.1 reinoud } 105 1.1 reinoud 106 1.1 reinoud 107 1.7 bjh21 static void 108 1.18 skrll qms_attach(device_t parent, device_t self, void *aux) 109 1.1 reinoud { 110 1.18 skrll struct qms_softc *sc = device_private(self); 111 1.7 bjh21 struct qms_attach_args *qa = aux; 112 1.7 bjh21 struct wsmousedev_attach_args wsmouseargs; 113 1.1 reinoud 114 1.18 skrll sc->sc_dev = self; 115 1.7 bjh21 sc->sc_iot = qa->qa_iot; 116 1.7 bjh21 sc->sc_ioh = qa->qa_ioh; 117 1.7 bjh21 sc->sc_butioh = qa->qa_ioh_but; 118 1.1 reinoud 119 1.7 bjh21 /* set up wsmouse attach arguments */ 120 1.7 bjh21 wsmouseargs.accessops = &qms_accessops; 121 1.7 bjh21 wsmouseargs.accesscookie = sc; 122 1.1 reinoud 123 1.18 skrll aprint_normal("\n"); 124 1.1 reinoud 125 1.7 bjh21 sc->sc_wsmousedev = 126 1.21 thorpej config_found(sc->sc_dev, &wsmouseargs, wsmousedevprint, CFARGS_NONE); 127 1.1 reinoud 128 1.12 ad callout_init(&sc->sc_callout, 0); 129 1.1 reinoud } 130 1.1 reinoud 131 1.1 reinoud 132 1.7 bjh21 static int 133 1.7 bjh21 qms_enable(void *cookie) 134 1.1 reinoud { 135 1.7 bjh21 struct qms_softc *sc = cookie; 136 1.7 bjh21 int b; 137 1.1 reinoud 138 1.7 bjh21 /* We don't want the mouse to warp on open. */ 139 1.7 bjh21 sc->lastx = bus_space_read_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX); 140 1.7 bjh21 sc->lasty = bus_space_read_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEY); 141 1.7 bjh21 b = bus_space_read_1(sc->sc_iot, sc->sc_butioh, QMS_BUTTONS) & 0x70; 142 1.1 reinoud 143 1.7 bjh21 /* patch up the buttons */ 144 1.1 reinoud b >>= 4; 145 1.7 bjh21 sc->lastb = ~( ((b & 1)<<2) | (b & 2) | ((b & 4)>>2)); 146 1.1 reinoud 147 1.7 bjh21 callout_reset(&sc->sc_callout, hz / 100, qms_intr, sc); 148 1.7 bjh21 return 0; 149 1.1 reinoud } 150 1.1 reinoud 151 1.1 reinoud 152 1.7 bjh21 static void 153 1.7 bjh21 qms_disable(void *cookie) 154 1.1 reinoud { 155 1.7 bjh21 struct qms_softc *sc = cookie; 156 1.1 reinoud 157 1.7 bjh21 callout_stop(&sc->sc_callout); 158 1.1 reinoud } 159 1.1 reinoud 160 1.1 reinoud 161 1.7 bjh21 static int 162 1.11 christos qms_ioctl(void *cookie, u_long cmd, void *data, int flag, struct lwp *l) 163 1.1 reinoud { 164 1.1 reinoud 165 1.7 bjh21 switch (cmd) { 166 1.7 bjh21 case WSMOUSEIO_GTYPE: 167 1.7 bjh21 *(int *)data = WSMOUSE_TYPE_ARCHIMEDES; 168 1.7 bjh21 return 0; 169 1.1 reinoud } 170 1.1 reinoud 171 1.7 bjh21 return EPASSTHROUGH; 172 1.1 reinoud } 173 1.3 jdolecek 174 1.7 bjh21 175 1.3 jdolecek static void 176 1.7 bjh21 qms_intr(void *arg) 177 1.3 jdolecek { 178 1.7 bjh21 struct qms_softc *sc = arg; 179 1.7 bjh21 int b; 180 1.17 skrll uint16_t x, y; 181 1.7 bjh21 int16_t dx, dy; 182 1.7 bjh21 183 1.7 bjh21 x = bus_space_read_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX); 184 1.7 bjh21 y = bus_space_read_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEY); 185 1.7 bjh21 b = bus_space_read_1(sc->sc_iot, sc->sc_butioh, QMS_BUTTONS) & 0x70; 186 1.3 jdolecek 187 1.7 bjh21 /* patch up the buttons */ 188 1.7 bjh21 b >>= 4; 189 1.7 bjh21 b = ~( ((b & 1)<<2) | (b & 2) | ((b & 4)>>2)); 190 1.3 jdolecek 191 1.7 bjh21 if ((x != sc->lastx) || (y != sc->lasty) || (b != sc->lastb)) { 192 1.7 bjh21 /* This assumes that int16_t is two's complement. */ 193 1.7 bjh21 dx = x - sc->lastx; 194 1.7 bjh21 dy = y - sc->lasty; 195 1.10 plunky wsmouse_input(sc->sc_wsmousedev, 196 1.10 plunky b, 197 1.10 plunky dx, dy, 0, 0, 198 1.10 plunky WSMOUSE_INPUT_DELTA); 199 1.3 jdolecek 200 1.7 bjh21 /* save old values */ 201 1.7 bjh21 sc->lastx = x; 202 1.7 bjh21 sc->lasty = y; 203 1.7 bjh21 sc->lastb = b; 204 1.9 bjh21 } 205 1.7 bjh21 callout_reset(&sc->sc_callout, hz / 100, qms_intr, sc); 206 1.3 jdolecek } 207 1.3 jdolecek 208 1.1 reinoud 209 1.7 bjh21 /* end of qms.c */ 210