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