1 /* $NetBSD: ms_ap.c,v 1.1 2000/11/15 14:04:05 tsubai 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/adrsmap.h> 37 #include <newsmips/apbus/apbusvar.h> 38 39 struct msreg { 40 u_int ms_data; 41 u_int ms_stat; 42 u_int ms_intr_en; 43 u_int ms_reset; 44 u_int ms_speed; 45 }; 46 47 struct ms_ap_softc { 48 struct device sc_dev; 49 volatile struct msreg *sc_reg; 50 struct device *sc_wsmousedev; 51 int sc_ndata; 52 u_char sc_buf[3]; 53 }; 54 55 int ms_ap_match(struct device *, struct cfdata *, void *); 56 void ms_ap_attach(struct device *, struct device *, void *); 57 int ms_ap_intr(void *); 58 59 int ms_ap_enable(void *); 60 int ms_ap_ioctl(void *, u_long, caddr_t, int, struct proc *); 61 void ms_ap_disable(void *); 62 63 struct cfattach ms_ap_ca = { 64 sizeof(struct ms_ap_softc), ms_ap_match, ms_ap_attach 65 }; 66 67 struct wsmouse_accessops ms_ap_accessops = { 68 ms_ap_enable, 69 ms_ap_ioctl, 70 ms_ap_disable 71 }; 72 73 int 74 ms_ap_match(parent, cf, aux) 75 struct device *parent; 76 struct cfdata *cf; 77 void *aux; 78 { 79 struct apbus_attach_args *apa = aux; 80 81 if (strcmp(apa->apa_name, "ms") == 0) 82 return 1; 83 84 return 0; 85 } 86 87 void 88 ms_ap_attach(parent, self, aux) 89 struct device *parent, *self; 90 void *aux; 91 { 92 struct ms_ap_softc *sc = (void *)self; 93 struct apbus_attach_args *apa = aux; 94 volatile struct msreg *reg = (void *)apa->apa_hwbase; 95 struct wsmousedev_attach_args aa; 96 97 printf(" slot%d addr 0x%lx\n", apa->apa_slotno, apa->apa_hwbase); 98 99 sc->sc_reg = reg; 100 101 reg->ms_reset = 0x03; 102 reg->ms_speed = 0x01; 103 reg->ms_intr_en = 0; 104 105 apbus_intr_establish(1, NEWS5000_INT1_KBD, 0, ms_ap_intr, sc, 106 "", apa->apa_ctlnum); 107 108 aa.accessops = &ms_ap_accessops; 109 aa.accesscookie = sc; 110 sc->sc_wsmousedev = config_found(self, &aa, wsmousedevprint); 111 } 112 113 int 114 ms_ap_intr(v) 115 void *v; 116 { 117 struct ms_ap_softc *sc = v; 118 volatile struct msreg *reg = sc->sc_reg; 119 int code, index, byte0, byte1, byte2; 120 int button, dx, dy; 121 int rv = 0; 122 123 reg->ms_intr_en = 0; 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 reg->ms_intr_en = 1; 176 return rv; 177 } 178 179 int 180 ms_ap_enable(v) 181 void *v; 182 { 183 struct ms_ap_softc *sc = v; 184 volatile struct msreg *reg = sc->sc_reg; 185 186 reg->ms_intr_en = 1; 187 return 0; 188 } 189 190 void 191 ms_ap_disable(v) 192 void *v; 193 { 194 struct ms_ap_softc *sc = v; 195 volatile struct msreg *reg = sc->sc_reg; 196 197 reg->ms_intr_en = 0; 198 } 199 200 int 201 ms_ap_ioctl(v, cmd, data, flag, p) 202 void *v; 203 u_long cmd; 204 caddr_t data; 205 int flag; 206 struct proc *p; 207 { 208 return -1; 209 } 210