1 /* $NetBSD: ms_hb.c,v 1.2 2002/03/17 19:40:46 atatat Exp $ */ 2 3 /*- 4 * Copyright (c) 2000 Tsubai Masanari. 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 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/param.h> 30 #include <sys/device.h> 31 #include <sys/systm.h> 32 33 #include <dev/wscons/wsconsio.h> 34 #include <dev/wscons/wsmousevar.h> 35 36 #include <machine/autoconf.h> 37 #include <machine/adrsmap.h> 38 39 struct msreg { 40 u_char ms_data; 41 u_char ms_stat; 42 u_char ms_reset; 43 u_char ms_init; 44 }; 45 46 struct ms_hb_softc { 47 struct device sc_dev; 48 volatile struct msreg *sc_reg; 49 struct device *sc_wsmousedev; 50 int sc_ndata; 51 u_char sc_buf[3]; 52 }; 53 54 int ms_hb_match(struct device *, struct cfdata *, void *); 55 void ms_hb_attach(struct device *, struct device *, void *); 56 int ms_hb_intr(void *); 57 58 int ms_hb_enable(void *); 59 int ms_hb_ioctl(void *, u_long, caddr_t, int, struct proc *); 60 void ms_hb_disable(void *); 61 62 struct cfattach ms_hb_ca = { 63 sizeof(struct ms_hb_softc), ms_hb_match, ms_hb_attach 64 }; 65 66 struct wsmouse_accessops ms_hb_accessops = { 67 ms_hb_enable, 68 ms_hb_ioctl, 69 ms_hb_disable 70 }; 71 72 int 73 ms_hb_match(parent, cf, aux) 74 struct device *parent; 75 struct cfdata *cf; 76 void *aux; 77 { 78 struct confargs *ca = aux; 79 80 if (strcmp(ca->ca_name, "ms") == 0) 81 return 1; 82 83 return 0; 84 } 85 86 void 87 ms_hb_attach(parent, self, aux) 88 struct device *parent, *self; 89 void *aux; 90 { 91 struct ms_hb_softc *sc = (void *)self; 92 volatile struct msreg *reg = (void *)self->dv_cfdata->cf_addr; 93 int intr = self->dv_cfdata->cf_level; 94 struct wsmousedev_attach_args aa; 95 96 if (intr == -1) 97 intr = 2; 98 99 sc->sc_reg = reg; 100 reg->ms_reset = 0x01; 101 reg->ms_init = 0x80; /* 1200 bps */ 102 103 printf(" level %d\n", intr); 104 105 hb_intr_establish(intr, IPL_TTY, ms_hb_intr, sc); 106 107 aa.accessops = &ms_hb_accessops; 108 aa.accesscookie = sc; 109 sc->sc_wsmousedev = config_found(self, &aa, wsmousedevprint); 110 } 111 112 int 113 ms_hb_intr(v) 114 void *v; 115 { 116 struct ms_hb_softc *sc = v; 117 volatile struct msreg *reg = sc->sc_reg; 118 volatile u_char *ien = (void *)INTEN0; 119 int code, index, byte0, byte1, byte2; 120 int button, dx, dy; 121 int rv = 0; 122 123 *ien &= ~RX_MSINTE; 124 125 while (reg->ms_stat & RX_MSRDY) { 126 rv = 1; 127 code = reg->ms_data; 128 index = sc->sc_ndata; 129 130 if (sc->sc_wsmousedev == NULL) 131 continue; 132 133 if (code & 0x80) { 134 sc->sc_buf[0] = code; 135 sc->sc_ndata = 1; 136 continue; 137 } 138 139 if (index == 1) { 140 sc->sc_buf[1] = code; 141 sc->sc_ndata++; 142 continue; 143 } 144 145 if (index == 2) { 146 sc->sc_buf[2] = code; 147 sc->sc_ndata++; 148 149 byte0 = sc->sc_buf[0]; 150 byte1 = sc->sc_buf[1]; 151 byte2 = sc->sc_buf[2]; 152 153 button = 0; 154 if (byte0 & 0x01) 155 button |= 1; 156 if (byte0 & 0x04) 157 button |= 2; 158 if (byte0 & 0x02) 159 button |= 4; 160 161 if (byte0 & 0x08) 162 dx = byte1 - 0x80; 163 else 164 dx = byte1; 165 if (byte0 & 0x10) 166 dy = byte2 - 0x80; 167 else 168 dy = byte2; 169 170 wsmouse_input(sc->sc_wsmousedev, button, dx, -dy, 0, 171 WSMOUSE_INPUT_DELTA); 172 } 173 } 174 175 *ien |= RX_MSINTE; 176 return rv; 177 } 178 179 int 180 ms_hb_enable(v) 181 void *v; 182 { 183 volatile u_char *ien = (void *)INTEN0; 184 185 *ien |= RX_MSINTE; 186 return 0; 187 } 188 189 void 190 ms_hb_disable(v) 191 void *v; 192 { 193 volatile u_char *ien = (void *)INTEN0; 194 195 *ien &= ~RX_MSINTE; 196 } 197 198 int 199 ms_hb_ioctl(v, cmd, data, flag, p) 200 void *v; 201 u_long cmd; 202 caddr_t data; 203 int flag; 204 struct proc *p; 205 { 206 return EPASSTHROUGH; 207 } 208