dtms.c revision 1.2
1/*	$NetBSD: dtms.c,v 1.2 2003/12/13 23:04:38 ad Exp $	*/
2
3/*-
4 * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *        This product includes software developed by the NetBSD
21 *        Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 *    contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39#include <sys/cdefs.h>
40__KERNEL_RCSID(0, "$NetBSD: dtms.c,v 1.2 2003/12/13 23:04:38 ad Exp $");
41
42#include "locators.h"
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/device.h>
47#include <sys/ioctl.h>
48#include <sys/syslog.h>
49
50#include <machine/bus.h>
51
52#include <arch/pmax/tc/dtreg.h>
53#include <arch/pmax/tc/dtvar.h>
54
55#include <dev/wscons/wsconsio.h>
56#include <dev/wscons/wsmousevar.h>
57
58#define	GET_SHORT(b0, b1)	(((b0) << 8) | (b1))
59
60struct dtms_softc {
61	struct device	sc_dv;
62	struct device	*sc_wsmousedev;
63	int		sc_enabled;
64};
65
66int	dtms_match(struct device *, struct cfdata *, void *);
67void	dtms_attach(struct device *, struct device *, void *);
68int	dtms_input(void *, int);
69int	dtms_enable(void *);
70int	dtms_ioctl(void *, u_long, caddr_t, int, struct proc *);
71void	dtms_disable(void *);
72void	dtms_handler(void *);
73
74CFATTACH_DECL(dtms, sizeof(struct dtms_softc),
75    dtms_match, dtms_attach, NULL, NULL);
76
77const struct wsmouse_accessops dtms_accessops = {
78	dtms_enable,
79	dtms_ioctl,
80	dtms_disable,
81};
82
83int
84dtms_match(struct device *parent, struct cfdata *cf, void *aux)
85{
86	struct dt_attach_args *dta;
87	struct dt_ident ident;
88
89	dta = aux;
90
91	/*
92	 * Allow hard-wiring of addresses.
93	 */
94	if (cf->cf_loc[DTCF_ADDR] == dta->dta_addr)
95		return (2);
96
97	/*
98	 * The keyboard and mouse addresses are often swapped.  So, we
99	 * accept the standard address for either, and ask the device to
100	 * identify itself.
101	 */
102	if (cf->cf_loc[DTCF_ADDR] == DTCF_ADDR_DEFAULT &&
103	    (dta->dta_addr == DT_ADDR_KBD || dta->dta_addr == DT_ADDR_MOUSE)) {
104		if (dt_identify(dta->dta_addr, &ident))
105			return (dta->dta_addr == DT_ADDR_MOUSE);
106		return (strncmp(ident.vendor, "DEC     ", 8) == 0 &&
107		    strncmp(ident.module, "VSXXX-", 6) == 0);
108	}
109
110	return (0);
111}
112
113void
114dtms_attach(struct device *parent, struct device *self, void *aux)
115{
116	struct dt_attach_args *dta;
117	struct wsmousedev_attach_args a;
118	struct dtms_softc *sc;
119	struct dt_softc *dt;
120
121	dt = (struct dt_softc *)parent;
122	sc = (struct dtms_softc *)self;
123	dta = aux;
124
125	printf("\n");
126
127	if (dt_establish_handler((struct dt_softc *)parent, dta->dta_addr,
128	    self, dtms_handler)) {
129		printf("%s: unable to establish handler\n", self->dv_xname);
130		return;
131	}
132
133	a.accessops = &dtms_accessops;
134	a.accesscookie = sc;
135	sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
136}
137
138int
139dtms_enable(void *cookie)
140{
141	struct dtms_softc *sc;
142
143	sc = cookie;
144	if (sc->sc_enabled)
145		return (EBUSY);
146	sc->sc_enabled = 1;
147
148	return (0);
149}
150
151void
152dtms_disable(void *cookie)
153{
154	struct dtms_softc *sc;
155
156	sc = cookie;
157	sc->sc_enabled = 0;
158}
159
160int
161dtms_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
162{
163
164	if (cmd == WSMOUSEIO_GTYPE) {
165		*(u_int *)data = WSMOUSE_TYPE_VSXXX;
166		return (0);
167	}
168
169	return (-1);
170}
171
172void
173dtms_handler(void *cookie)
174{
175	struct dtms_softc *sc;
176	struct dt_softc *dt;
177	struct dt_device *dtdv;
178	struct dt_msg *msg;
179	int buttons, dx, dy, tmp;
180
181	dtdv = cookie;
182	sc = (struct dtms_softc *)dtdv->dtdv_dv;
183	dt = (struct dt_softc *)sc->sc_dv.dv_parent;
184
185	while ((msg = dt_msg_dequeue(dtdv)) != NULL) {
186		if (sc->sc_enabled && !msg->code.val.P) {
187			tmp = GET_SHORT(msg->body[0], msg->body[1]);
188			buttons = ((tmp >> 1) & 0x3) | ((tmp << 2) & 0x4);
189
190			tmp = GET_SHORT(msg->body[2], msg->body[3]);
191			if (tmp < 0)
192				dx = -(-tmp & 0x1f);
193			else
194				dx = tmp & 0x1f;
195
196			tmp = GET_SHORT(msg->body[4], msg->body[5]);
197			if (tmp < 0)
198				dy = -(-tmp & 0x1f);
199			else
200				dy = tmp & 0x1f;
201
202			wsmouse_input(sc->sc_wsmousedev, buttons, dx, dy, 0,
203			    WSMOUSE_INPUT_DELTA);
204		}
205
206		dt_msg_release(dt, msg);
207	}
208}
209