ms_hb.c revision 1.4 1 /* $NetBSD: ms_hb.c,v 1.4 2002/10/02 04:27:52 thorpej 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 CFATTACH_DECL(ms_hb, sizeof(struct ms_hb_softc),
63 ms_hb_match, ms_hb_attach, NULL, NULL);
64
65 struct wsmouse_accessops ms_hb_accessops = {
66 ms_hb_enable,
67 ms_hb_ioctl,
68 ms_hb_disable
69 };
70
71 int
72 ms_hb_match(parent, cf, aux)
73 struct device *parent;
74 struct cfdata *cf;
75 void *aux;
76 {
77 struct confargs *ca = aux;
78
79 if (strcmp(ca->ca_name, "ms") == 0)
80 return 1;
81
82 return 0;
83 }
84
85 void
86 ms_hb_attach(parent, self, aux)
87 struct device *parent, *self;
88 void *aux;
89 {
90 struct ms_hb_softc *sc = (void *)self;
91 volatile struct msreg *reg = (void *)self->dv_cfdata->cf_addr;
92 int intr = self->dv_cfdata->cf_level;
93 struct wsmousedev_attach_args aa;
94
95 if (intr == -1)
96 intr = 2;
97
98 sc->sc_reg = reg;
99 reg->ms_reset = 0x01;
100 reg->ms_init = 0x80; /* 1200 bps */
101
102 printf(" level %d\n", intr);
103
104 hb_intr_establish(intr, IPL_TTY, ms_hb_intr, sc);
105
106 aa.accessops = &ms_hb_accessops;
107 aa.accesscookie = sc;
108 sc->sc_wsmousedev = config_found(self, &aa, wsmousedevprint);
109 }
110
111 int
112 ms_hb_intr(v)
113 void *v;
114 {
115 struct ms_hb_softc *sc = v;
116 volatile struct msreg *reg = sc->sc_reg;
117 volatile u_char *ien = (void *)INTEN0;
118 int code, index, byte0, byte1, byte2;
119 int button, dx, dy;
120 int rv = 0;
121
122 *ien &= ~RX_MSINTE;
123
124 while (reg->ms_stat & RX_MSRDY) {
125 rv = 1;
126 code = reg->ms_data;
127 index = sc->sc_ndata;
128
129 if (sc->sc_wsmousedev == NULL)
130 continue;
131
132 if (code & 0x80) {
133 sc->sc_buf[0] = code;
134 sc->sc_ndata = 1;
135 continue;
136 }
137
138 if (index == 1) {
139 sc->sc_buf[1] = code;
140 sc->sc_ndata++;
141 continue;
142 }
143
144 if (index == 2) {
145 sc->sc_buf[2] = code;
146 sc->sc_ndata++;
147
148 byte0 = sc->sc_buf[0];
149 byte1 = sc->sc_buf[1];
150 byte2 = sc->sc_buf[2];
151
152 button = 0;
153 if (byte0 & 0x01)
154 button |= 1;
155 if (byte0 & 0x04)
156 button |= 2;
157 if (byte0 & 0x02)
158 button |= 4;
159
160 if (byte0 & 0x08)
161 dx = byte1 - 0x80;
162 else
163 dx = byte1;
164 if (byte0 & 0x10)
165 dy = byte2 - 0x80;
166 else
167 dy = byte2;
168
169 wsmouse_input(sc->sc_wsmousedev, button, dx, -dy, 0,
170 WSMOUSE_INPUT_DELTA);
171 }
172 }
173
174 *ien |= RX_MSINTE;
175 return rv;
176 }
177
178 int
179 ms_hb_enable(v)
180 void *v;
181 {
182 volatile u_char *ien = (void *)INTEN0;
183
184 *ien |= RX_MSINTE;
185 return 0;
186 }
187
188 void
189 ms_hb_disable(v)
190 void *v;
191 {
192 volatile u_char *ien = (void *)INTEN0;
193
194 *ien &= ~RX_MSINTE;
195 }
196
197 int
198 ms_hb_ioctl(v, cmd, data, flag, p)
199 void *v;
200 u_long cmd;
201 caddr_t data;
202 int flag;
203 struct proc *p;
204 {
205 return EPASSTHROUGH;
206 }
207