FreeBSD/Linux Kernel Cross Reference
sys/dev/dec/dzms.c
1 /* $NetBSD: dzms.c,v 1.15 2006/11/12 19:00:43 plunky Exp $ */
2
3 /*
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
10 *
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratory.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 * @(#)ms.c 8.1 (Berkeley) 6/11/93
41 */
42
43 /*
44 * VSXXX mice attached to line 1 of the DZ*
45 */
46
47 #include <sys/cdefs.h>
48 __KERNEL_RCSID(0, "$NetBSD: dzms.c,v 1.15 2006/11/12 19:00:43 plunky Exp $");
49
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/device.h>
53 #include <sys/ioctl.h>
54 #include <sys/syslog.h>
55 #include <sys/kernel.h>
56 #include <sys/proc.h>
57 #include <sys/tty.h>
58
59 #include <machine/bus.h>
60
61 #include <dev/dec/dzreg.h>
62 #include <dev/dec/dzvar.h>
63 #include <dev/dec/dzkbdvar.h>
64 #include <dev/dec/lk201.h>
65
66 #include <dev/wscons/wsconsio.h>
67 #include <dev/wscons/wsmousevar.h>
68
69 #include "locators.h"
70
71 struct dzms_softc { /* driver status information */
72 struct device dzms_dev; /* required first: base device */
73 struct dz_linestate *dzms_ls;
74
75 int sc_enabled; /* input enabled? */
76 int sc_selftest;
77
78 int inputstate;
79 u_int buttons;
80 int dx, dy;
81
82 struct device *sc_wsmousedev;
83 };
84
85 static int dzms_match(struct device *, struct cfdata *, void *);
86 static void dzms_attach(struct device *, struct device *, void *);
87 static int dzms_input(void *, int);
88
89 CFATTACH_DECL(dzms, sizeof(struct dzms_softc),
90 dzms_match, dzms_attach, NULL, NULL);
91
92 static int dzms_enable(void *);
93 static int dzms_ioctl(void *, u_long, caddr_t, int, struct lwp *);
94 static void dzms_disable(void *);
95
96 const struct wsmouse_accessops dzms_accessops = {
97 dzms_enable,
98 dzms_ioctl,
99 dzms_disable,
100 };
101
102 static int
103 dzms_match(parent, cf, aux)
104 struct device *parent;
105 struct cfdata *cf;
106 void *aux;
107 {
108 struct dzkm_attach_args *daa = aux;
109
110 /* Exact match is better than wildcard. */
111 if (cf->cf_loc[DZCF_LINE] == daa->daa_line)
112 return 2;
113
114 /* This driver accepts wildcard. */
115 if (cf->cf_loc[DZCF_LINE] == DZCF_LINE_DEFAULT)
116 return 1;
117
118 return 0;
119 }
120
121 static void
122 dzms_attach(parent, self, aux)
123 struct device *parent, *self;
124 void *aux;
125 {
126 struct dz_softc *dz = device_private(parent);
127 struct dzms_softc *dzms = device_private(self);
128 struct dzkm_attach_args *daa = aux;
129 struct dz_linestate *ls;
130 struct wsmousedev_attach_args a;
131
132 dz->sc_dz[daa->daa_line].dz_catch = dzms_input;
133 dz->sc_dz[daa->daa_line].dz_private = dzms;
134 ls = &dz->sc_dz[daa->daa_line];
135 dzms->dzms_ls = ls;
136
137 printf("\n");
138
139 a.accessops = &dzms_accessops;
140 a.accesscookie = dzms;
141
142 dzms->sc_enabled = 0;
143 dzms->sc_selftest = 0;
144 dzms->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
145 }
146
147 static int
148 dzms_enable(v)
149 void *v;
150 {
151 struct dzms_softc *sc = v;
152
153 if (sc->sc_enabled)
154 return EBUSY;
155
156 sc->sc_selftest = 4; /* wait for 4 byte reply upto 1/2 sec */
157 dzputc(sc->dzms_ls, MOUSE_SELF_TEST);
158 (void)tsleep(dzms_enable, TTIPRI, "dzmsopen", hz / 2);
159 if (sc->sc_selftest != 0) {
160 sc->sc_selftest = 0;
161 return ENXIO;
162 }
163 DELAY(150);
164 dzputc(sc->dzms_ls, MOUSE_INCREMENTAL);
165 sc->sc_enabled = 1;
166 sc->inputstate = 0;
167 return 0;
168 }
169
170 static void
171 dzms_disable(v)
172 void *v;
173 {
174 struct dzms_softc *sc = v;
175
176 sc->sc_enabled = 0;
177 }
178
179 static int
180 dzms_ioctl(v, cmd, data, flag, l)
181 void *v;
182 u_long cmd;
183 caddr_t data;
184 int flag;
185 struct lwp *l;
186 {
187 if (cmd == WSMOUSEIO_GTYPE) {
188 *(u_int *)data = WSMOUSE_TYPE_VSXXX;
189 return 0;
190 }
191 return EPASSTHROUGH;
192 }
193
194 static int
195 dzms_input(vsc, data)
196 void *vsc;
197 int data;
198 {
199 struct dzms_softc *sc = vsc;
200
201 if (sc->sc_enabled == 0) {
202 if (sc->sc_selftest > 0) {
203 sc->sc_selftest -= 1;
204 if (sc->sc_selftest == 0)
205 wakeup(dzms_enable);
206 }
207 return (1);
208 }
209
210 #define WSMS_BUTTON1 0x01
211 #define WSMS_BUTTON2 0x02
212 #define WSMS_BUTTON3 0x04
213
214 if ((data & MOUSE_START_FRAME) != 0)
215 sc->inputstate = 1;
216 else
217 sc->inputstate++;
218
219 if (sc->inputstate == 1) {
220 sc->buttons = 0;
221 if ((data & LEFT_BUTTON) != 0)
222 sc->buttons |= WSMS_BUTTON1;
223 if ((data & MIDDLE_BUTTON) != 0)
224 sc->buttons |= WSMS_BUTTON2;
225 if ((data & RIGHT_BUTTON) != 0)
226 sc->buttons |= WSMS_BUTTON3;
227
228 sc->dx = data & MOUSE_X_SIGN;
229 sc->dy = data & MOUSE_Y_SIGN;
230 } else if (sc->inputstate == 2) {
231 if (sc->dx == 0)
232 sc->dx = -data;
233 else
234 sc->dx = data;
235 } else if (sc->inputstate == 3) {
236 sc->inputstate = 0;
237 if (sc->dy == 0)
238 sc->dy = -data;
239 else
240 sc->dy = data;
241 wsmouse_input(sc->sc_wsmousedev,
242 sc->buttons,
243 sc->dx, sc->dy, 0, 0,
244 WSMOUSE_INPUT_DELTA);
245 }
246
247 return(1);
248 }
249
Cache object: 95902e095abe28ecc2fe9858b5bc8604
|