uep.c revision 1.2.2.2 1 1.2.2.2 skrll /* $NetBSD: uep.c,v 1.2.2.2 2004/08/03 10:51:33 skrll Exp $ */
2 1.2.2.2 skrll
3 1.2.2.2 skrll /*
4 1.2.2.2 skrll * Copyright (c) 2004 The NetBSD Foundation, Inc.
5 1.2.2.2 skrll * All rights reserved.
6 1.2.2.2 skrll *
7 1.2.2.2 skrll * This code is derived from software contributed to The NetBSD Foundation
8 1.2.2.2 skrll * by Tyler C. Sarna (tsarna (at) netbsd.org).
9 1.2.2.2 skrll *
10 1.2.2.2 skrll * Redistribution and use in source and binary forms, with or without
11 1.2.2.2 skrll * modification, are permitted provided that the following conditions
12 1.2.2.2 skrll * are met:
13 1.2.2.2 skrll * 1. Redistributions of source code must retain the above copyright
14 1.2.2.2 skrll * notice, this list of conditions and the following disclaimer.
15 1.2.2.2 skrll * 2. Redistributions in binary form must reproduce the above copyright
16 1.2.2.2 skrll * notice, this list of conditions and the following disclaimer in the
17 1.2.2.2 skrll * documentation and/or other materials provided with the distribution.
18 1.2.2.2 skrll * 3. All advertising materials mentioning features or use of this software
19 1.2.2.2 skrll * must display the following acknowledgement:
20 1.2.2.2 skrll * This product includes software developed by the NetBSD
21 1.2.2.2 skrll * Foundation, Inc. and its contributors.
22 1.2.2.2 skrll * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.2.2.2 skrll * contributors may be used to endorse or promote products derived
24 1.2.2.2 skrll * from this software without specific prior written permission.
25 1.2.2.2 skrll *
26 1.2.2.2 skrll * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.2.2.2 skrll * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.2.2.2 skrll * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.2.2.2 skrll * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.2.2.2 skrll * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.2.2.2 skrll * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.2.2.2 skrll * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.2.2.2 skrll * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.2.2.2 skrll * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.2.2.2 skrll * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.2.2.2 skrll * POSSIBILITY OF SUCH DAMAGE.
37 1.2.2.2 skrll */
38 1.2.2.2 skrll
39 1.2.2.2 skrll /*
40 1.2.2.2 skrll * eGalax USB touchpanel controller driver.
41 1.2.2.2 skrll *
42 1.2.2.2 skrll * For Programming Documentation, see:
43 1.2.2.2 skrll *
44 1.2.2.2 skrll * http://www.egalax.com/SoftwareProgrammingGuide_1.1.pdf
45 1.2.2.2 skrll */
46 1.2.2.2 skrll
47 1.2.2.2 skrll #include <sys/cdefs.h>
48 1.2.2.2 skrll __KERNEL_RCSID(0, "$NetBSD: uep.c,v 1.2.2.2 2004/08/03 10:51:33 skrll Exp $");
49 1.2.2.2 skrll
50 1.2.2.2 skrll #include <sys/param.h>
51 1.2.2.2 skrll #include <sys/systm.h>
52 1.2.2.2 skrll #include <sys/kernel.h>
53 1.2.2.2 skrll #include <sys/malloc.h>
54 1.2.2.2 skrll #include <sys/device.h>
55 1.2.2.2 skrll #include <sys/ioctl.h>
56 1.2.2.2 skrll #include <sys/vnode.h>
57 1.2.2.2 skrll
58 1.2.2.2 skrll #include <dev/usb/usb.h>
59 1.2.2.2 skrll #include <dev/usb/usbdi.h>
60 1.2.2.2 skrll #include <dev/usb/usbdi_util.h>
61 1.2.2.2 skrll #include <dev/usb/usbdevs.h>
62 1.2.2.2 skrll #include <dev/usb/usb_quirks.h>
63 1.2.2.2 skrll
64 1.2.2.2 skrll #include <dev/wscons/wsconsio.h>
65 1.2.2.2 skrll #include <dev/wscons/wsmousevar.h>
66 1.2.2.2 skrll #include <dev/wscons/tpcalibvar.h>
67 1.2.2.2 skrll
68 1.2.2.2 skrll #define UIDSTR "eGalax USB SN000000"
69 1.2.2.2 skrll
70 1.2.2.2 skrll struct uep_softc {
71 1.2.2.2 skrll USBBASEDEVICE sc_dev;
72 1.2.2.2 skrll usbd_device_handle sc_udev; /* device */
73 1.2.2.2 skrll usbd_interface_handle sc_iface; /* interface */
74 1.2.2.2 skrll int sc_iface_number;
75 1.2.2.2 skrll
76 1.2.2.2 skrll int sc_intr_number; /* interrupt number */
77 1.2.2.2 skrll usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */
78 1.2.2.2 skrll u_char *sc_ibuf;
79 1.2.2.2 skrll int sc_isize;
80 1.2.2.2 skrll
81 1.2.2.2 skrll device_ptr_t sc_wsmousedev; /* wsmouse device */
82 1.2.2.2 skrll struct tpcalib_softc sc_tpcalib; /* calibration */
83 1.2.2.2 skrll
84 1.2.2.2 skrll u_char sc_enabled;
85 1.2.2.2 skrll u_char sc_dying;
86 1.2.2.2 skrll };
87 1.2.2.2 skrll
88 1.2.2.2 skrll static struct wsmouse_calibcoords default_calib = {
89 1.2.2.2 skrll 0, 0, 2047, 2047,
90 1.2.2.2 skrll WSMOUSE_CALIBCOORDS_RESET,
91 1.2.2.2 skrll };
92 1.2.2.2 skrll
93 1.2.2.2 skrll Static void uep_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
94 1.2.2.2 skrll
95 1.2.2.2 skrll Static int uep_enable(void *);
96 1.2.2.2 skrll Static void uep_disable(void *);
97 1.2.2.2 skrll Static int uep_ioctl(void *, u_long, caddr_t, int, usb_proc_ptr);
98 1.2.2.2 skrll
99 1.2.2.2 skrll const struct wsmouse_accessops uep_accessops = {
100 1.2.2.2 skrll uep_enable,
101 1.2.2.2 skrll uep_ioctl,
102 1.2.2.2 skrll uep_disable,
103 1.2.2.2 skrll };
104 1.2.2.2 skrll
105 1.2.2.2 skrll USB_DECLARE_DRIVER(uep);
106 1.2.2.2 skrll
107 1.2.2.2 skrll USB_MATCH(uep)
108 1.2.2.2 skrll {
109 1.2.2.2 skrll USB_MATCH_START(uep, uaa);
110 1.2.2.2 skrll
111 1.2.2.2 skrll if (uaa->iface == NULL)
112 1.2.2.2 skrll return UMATCH_NONE;
113 1.2.2.2 skrll
114 1.2.2.2 skrll if ((uaa->vendor == USB_VENDOR_EGALAX) && (
115 1.2.2.2 skrll (uaa->product == USB_PRODUCT_EGALAX_TPANEL)
116 1.2.2.2 skrll || (uaa->product == USB_PRODUCT_EGALAX_TPANEL2)
117 1.2.2.2 skrll ))
118 1.2.2.2 skrll return UMATCH_VENDOR_PRODUCT;
119 1.2.2.2 skrll
120 1.2.2.2 skrll if ((uaa->vendor == USB_VENDOR_EGALAX2)
121 1.2.2.2 skrll && (uaa->product == USB_PRODUCT_EGALAX2_TPANEL))
122 1.2.2.2 skrll return UMATCH_VENDOR_PRODUCT;
123 1.2.2.2 skrll
124 1.2.2.2 skrll
125 1.2.2.2 skrll return UMATCH_NONE;
126 1.2.2.2 skrll }
127 1.2.2.2 skrll
128 1.2.2.2 skrll USB_ATTACH(uep)
129 1.2.2.2 skrll {
130 1.2.2.2 skrll USB_ATTACH_START(uep, sc, uaa);
131 1.2.2.2 skrll usbd_device_handle dev = uaa->device;
132 1.2.2.2 skrll usb_config_descriptor_t *cdesc;
133 1.2.2.2 skrll usb_interface_descriptor_t *id;
134 1.2.2.2 skrll usb_endpoint_descriptor_t *ed;
135 1.2.2.2 skrll struct wsmousedev_attach_args a;
136 1.2.2.2 skrll char devinfo[1024];
137 1.2.2.2 skrll usbd_status err;
138 1.2.2.2 skrll int i, found;
139 1.2.2.2 skrll
140 1.2.2.2 skrll usbd_devinfo(dev, 0, devinfo, sizeof(devinfo));
141 1.2.2.2 skrll
142 1.2.2.2 skrll USB_ATTACH_SETUP;
143 1.2.2.2 skrll
144 1.2.2.2 skrll printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
145 1.2.2.2 skrll
146 1.2.2.2 skrll sc->sc_udev = dev;
147 1.2.2.2 skrll sc->sc_intr_number = -1;
148 1.2.2.2 skrll sc->sc_intr_pipe = NULL;
149 1.2.2.2 skrll sc->sc_enabled = sc->sc_isize = 0;
150 1.2.2.2 skrll
151 1.2.2.2 skrll /* Move the device into the configured state. */
152 1.2.2.2 skrll err = usbd_set_config_index(dev, 0, 1);
153 1.2.2.2 skrll if (err) {
154 1.2.2.2 skrll printf("\n%s: failed to set configuration, err=%s\n",
155 1.2.2.2 skrll USBDEVNAME(sc->sc_dev), usbd_errstr(err));
156 1.2.2.2 skrll sc->sc_dying = 1;
157 1.2.2.2 skrll USB_ATTACH_ERROR_RETURN;
158 1.2.2.2 skrll }
159 1.2.2.2 skrll
160 1.2.2.2 skrll /* get the config descriptor */
161 1.2.2.2 skrll cdesc = usbd_get_config_descriptor(sc->sc_udev);
162 1.2.2.2 skrll if (cdesc == NULL) {
163 1.2.2.2 skrll printf("%s: failed to get configuration descriptor\n",
164 1.2.2.2 skrll USBDEVNAME(sc->sc_dev));
165 1.2.2.2 skrll sc->sc_dying = 1;
166 1.2.2.2 skrll USB_ATTACH_ERROR_RETURN;
167 1.2.2.2 skrll }
168 1.2.2.2 skrll
169 1.2.2.2 skrll /* get the interface */
170 1.2.2.2 skrll err = usbd_device2interface_handle(dev, 0, &sc->sc_iface);
171 1.2.2.2 skrll if (err) {
172 1.2.2.2 skrll printf("\n%s: failed to get interface, err=%s\n",
173 1.2.2.2 skrll USBDEVNAME(sc->sc_dev), usbd_errstr(err));
174 1.2.2.2 skrll sc->sc_dying = 1;
175 1.2.2.2 skrll USB_ATTACH_ERROR_RETURN;
176 1.2.2.2 skrll }
177 1.2.2.2 skrll
178 1.2.2.2 skrll /* Find the interrupt endpoint */
179 1.2.2.2 skrll id = usbd_get_interface_descriptor(sc->sc_iface);
180 1.2.2.2 skrll sc->sc_iface_number = id->bInterfaceNumber;
181 1.2.2.2 skrll found = 0;
182 1.2.2.2 skrll
183 1.2.2.2 skrll for (i = 0; i < id->bNumEndpoints; i++) {
184 1.2.2.2 skrll ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
185 1.2.2.2 skrll if (ed == NULL) {
186 1.2.2.2 skrll printf("%s: no endpoint descriptor for %d\n",
187 1.2.2.2 skrll USBDEVNAME(sc->sc_dev), i);
188 1.2.2.2 skrll sc->sc_dying = 1;
189 1.2.2.2 skrll USB_ATTACH_ERROR_RETURN;
190 1.2.2.2 skrll }
191 1.2.2.2 skrll
192 1.2.2.2 skrll if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
193 1.2.2.2 skrll UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
194 1.2.2.2 skrll sc->sc_intr_number = ed->bEndpointAddress;
195 1.2.2.2 skrll sc->sc_isize = UGETW(ed->wMaxPacketSize);
196 1.2.2.2 skrll }
197 1.2.2.2 skrll }
198 1.2.2.2 skrll
199 1.2.2.2 skrll if (sc->sc_intr_number== -1) {
200 1.2.2.2 skrll printf("%s: Could not find interrupt in\n",
201 1.2.2.2 skrll USBDEVNAME(sc->sc_dev));
202 1.2.2.2 skrll sc->sc_dying = 1;
203 1.2.2.2 skrll USB_ATTACH_ERROR_RETURN;
204 1.2.2.2 skrll }
205 1.2.2.2 skrll
206 1.2.2.2 skrll usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
207 1.2.2.2 skrll USBDEV(sc->sc_dev));
208 1.2.2.2 skrll
209 1.2.2.2 skrll a.accessops = &uep_accessops;
210 1.2.2.2 skrll a.accesscookie = sc;
211 1.2.2.2 skrll
212 1.2.2.2 skrll sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
213 1.2.2.2 skrll
214 1.2.2.2 skrll tpcalib_init(&sc->sc_tpcalib);
215 1.2.2.2 skrll tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS,
216 1.2.2.2 skrll (caddr_t)&default_calib, 0, 0);
217 1.2.2.2 skrll
218 1.2.2.2 skrll USB_ATTACH_SUCCESS_RETURN;
219 1.2.2.2 skrll }
220 1.2.2.2 skrll
221 1.2.2.2 skrll USB_DETACH(uep)
222 1.2.2.2 skrll {
223 1.2.2.2 skrll USB_DETACH_START(uep, sc);
224 1.2.2.2 skrll int rv = 0;
225 1.2.2.2 skrll
226 1.2.2.2 skrll if (sc->sc_intr_pipe != NULL) {
227 1.2.2.2 skrll usbd_abort_pipe(sc->sc_intr_pipe);
228 1.2.2.2 skrll usbd_close_pipe(sc->sc_intr_pipe);
229 1.2.2.2 skrll sc->sc_intr_pipe = NULL;
230 1.2.2.2 skrll }
231 1.2.2.2 skrll
232 1.2.2.2 skrll sc->sc_dying = 1;
233 1.2.2.2 skrll
234 1.2.2.2 skrll /* save current calib as defaults */
235 1.2.2.2 skrll default_calib = sc->sc_tpcalib.sc_saved;
236 1.2.2.2 skrll
237 1.2.2.2 skrll if (sc->sc_wsmousedev != NULL) {
238 1.2.2.2 skrll rv = config_detach(sc->sc_wsmousedev, flags);
239 1.2.2.2 skrll sc->sc_wsmousedev = NULL;
240 1.2.2.2 skrll }
241 1.2.2.2 skrll
242 1.2.2.2 skrll usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
243 1.2.2.2 skrll USBDEV(sc->sc_dev));
244 1.2.2.2 skrll
245 1.2.2.2 skrll return rv;
246 1.2.2.2 skrll }
247 1.2.2.2 skrll
248 1.2.2.2 skrll int
249 1.2.2.2 skrll uep_activate(device_ptr_t self, enum devact act)
250 1.2.2.2 skrll {
251 1.2.2.2 skrll struct uep_softc *sc = (struct uep_softc *)self;
252 1.2.2.2 skrll int rv = 0;
253 1.2.2.2 skrll
254 1.2.2.2 skrll switch (act) {
255 1.2.2.2 skrll case DVACT_ACTIVATE:
256 1.2.2.2 skrll return EOPNOTSUPP;
257 1.2.2.2 skrll
258 1.2.2.2 skrll case DVACT_DEACTIVATE:
259 1.2.2.2 skrll if (sc->sc_wsmousedev != NULL)
260 1.2.2.2 skrll rv = config_deactivate(sc->sc_wsmousedev);
261 1.2.2.2 skrll sc->sc_dying = 1;
262 1.2.2.2 skrll break;
263 1.2.2.2 skrll }
264 1.2.2.2 skrll
265 1.2.2.2 skrll return rv;
266 1.2.2.2 skrll }
267 1.2.2.2 skrll
268 1.2.2.2 skrll Static int
269 1.2.2.2 skrll uep_enable(void *v)
270 1.2.2.2 skrll {
271 1.2.2.2 skrll struct uep_softc *sc = v;
272 1.2.2.2 skrll int err;
273 1.2.2.2 skrll
274 1.2.2.2 skrll if (sc->sc_dying)
275 1.2.2.2 skrll return EIO;
276 1.2.2.2 skrll
277 1.2.2.2 skrll if (sc->sc_enabled)
278 1.2.2.2 skrll return EBUSY;
279 1.2.2.2 skrll
280 1.2.2.2 skrll if (sc->sc_isize == 0)
281 1.2.2.2 skrll return 0;
282 1.2.2.2 skrll sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
283 1.2.2.2 skrll err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_intr_number,
284 1.2.2.2 skrll USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc, sc->sc_ibuf,
285 1.2.2.2 skrll sc->sc_isize, uep_intr, USBD_DEFAULT_INTERVAL);
286 1.2.2.2 skrll if (err) {
287 1.2.2.2 skrll free(sc->sc_ibuf, M_USBDEV);
288 1.2.2.2 skrll sc->sc_intr_pipe = NULL;
289 1.2.2.2 skrll return EIO;
290 1.2.2.2 skrll }
291 1.2.2.2 skrll
292 1.2.2.2 skrll sc->sc_enabled = 1;
293 1.2.2.2 skrll
294 1.2.2.2 skrll return 0;
295 1.2.2.2 skrll }
296 1.2.2.2 skrll
297 1.2.2.2 skrll Static void
298 1.2.2.2 skrll uep_disable(void *v)
299 1.2.2.2 skrll {
300 1.2.2.2 skrll struct uep_softc *sc = v;
301 1.2.2.2 skrll
302 1.2.2.2 skrll if (!sc->sc_enabled) {
303 1.2.2.2 skrll printf("uep_disable: already disabled!\n");
304 1.2.2.2 skrll return;
305 1.2.2.2 skrll }
306 1.2.2.2 skrll
307 1.2.2.2 skrll /* Disable interrupts. */
308 1.2.2.2 skrll if (sc->sc_intr_pipe != NULL) {
309 1.2.2.2 skrll usbd_abort_pipe(sc->sc_intr_pipe);
310 1.2.2.2 skrll usbd_close_pipe(sc->sc_intr_pipe);
311 1.2.2.2 skrll sc->sc_intr_pipe = NULL;
312 1.2.2.2 skrll }
313 1.2.2.2 skrll
314 1.2.2.2 skrll if (sc->sc_ibuf != NULL) {
315 1.2.2.2 skrll free(sc->sc_ibuf, M_USBDEV);
316 1.2.2.2 skrll sc->sc_ibuf = NULL;
317 1.2.2.2 skrll }
318 1.2.2.2 skrll
319 1.2.2.2 skrll sc->sc_enabled = 0;
320 1.2.2.2 skrll }
321 1.2.2.2 skrll
322 1.2.2.2 skrll Static int
323 1.2.2.2 skrll uep_ioctl(void *v, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
324 1.2.2.2 skrll {
325 1.2.2.2 skrll struct uep_softc *sc = v;
326 1.2.2.2 skrll struct wsmouse_id *id;
327 1.2.2.2 skrll
328 1.2.2.2 skrll switch (cmd) {
329 1.2.2.2 skrll case WSMOUSEIO_GTYPE:
330 1.2.2.2 skrll *(u_int *)data = WSMOUSE_TYPE_TPANEL;
331 1.2.2.2 skrll return 0;
332 1.2.2.2 skrll
333 1.2.2.2 skrll case WSMOUSEIO_GETID:
334 1.2.2.2 skrll /*
335 1.2.2.2 skrll * return unique ID string
336 1.2.2.2 skrll * "<vendor> <model> <serial number>"
337 1.2.2.2 skrll * unfortunately we have no serial number...
338 1.2.2.2 skrll */
339 1.2.2.2 skrll id = (struct wsmouse_id *)data;
340 1.2.2.2 skrll if (id->type != WSMOUSE_ID_TYPE_UIDSTR)
341 1.2.2.2 skrll return EINVAL;
342 1.2.2.2 skrll
343 1.2.2.2 skrll strcpy(id->data, UIDSTR);
344 1.2.2.2 skrll id->length = strlen(UIDSTR);
345 1.2.2.2 skrll return 0;
346 1.2.2.2 skrll
347 1.2.2.2 skrll case WSMOUSEIO_SCALIBCOORDS:
348 1.2.2.2 skrll case WSMOUSEIO_GCALIBCOORDS:
349 1.2.2.2 skrll return tpcalib_ioctl(&sc->sc_tpcalib, cmd, data, flag, p);
350 1.2.2.2 skrll }
351 1.2.2.2 skrll
352 1.2.2.2 skrll return EPASSTHROUGH;
353 1.2.2.2 skrll }
354 1.2.2.2 skrll
355 1.2.2.2 skrll void
356 1.2.2.2 skrll uep_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
357 1.2.2.2 skrll {
358 1.2.2.2 skrll struct uep_softc *sc = addr;
359 1.2.2.2 skrll u_char *p = sc->sc_ibuf;
360 1.2.2.2 skrll u_int32_t len;
361 1.2.2.2 skrll int x = 0, y = 0, s;
362 1.2.2.2 skrll
363 1.2.2.2 skrll usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
364 1.2.2.2 skrll
365 1.2.2.2 skrll if (status == USBD_CANCELLED)
366 1.2.2.2 skrll return;
367 1.2.2.2 skrll
368 1.2.2.2 skrll if (status != USBD_NORMAL_COMPLETION) {
369 1.2.2.2 skrll printf("%s: status %d\n", USBDEVNAME(sc->sc_dev), status);
370 1.2.2.2 skrll usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
371 1.2.2.2 skrll return;
372 1.2.2.2 skrll }
373 1.2.2.2 skrll
374 1.2.2.2 skrll if (len != 5) {
375 1.2.2.2 skrll #if 0
376 1.2.2.2 skrll printf("%s: bad input length %d != %d\n",
377 1.2.2.2 skrll USBDEVNAME(sc->sc_dev), len, sc->sc_isize);
378 1.2.2.2 skrll #endif
379 1.2.2.2 skrll return;
380 1.2.2.2 skrll }
381 1.2.2.2 skrll
382 1.2.2.2 skrll if ((p[0] & 0xFE) != 0x80) {
383 1.2.2.2 skrll printf("%s: bad input packet format\n", USBDEVNAME(sc->sc_dev));
384 1.2.2.2 skrll return;
385 1.2.2.2 skrll }
386 1.2.2.2 skrll
387 1.2.2.2 skrll if (sc->sc_wsmousedev != NULL) {
388 1.2.2.2 skrll /*
389 1.2.2.2 skrll * Packet format is 5 bytes:
390 1.2.2.2 skrll *
391 1.2.2.2 skrll * 1000000T
392 1.2.2.2 skrll * 0000AAAA
393 1.2.2.2 skrll * 0AAAAAAA
394 1.2.2.2 skrll * 0000BBBB
395 1.2.2.2 skrll * 0BBBBBBB
396 1.2.2.2 skrll *
397 1.2.2.2 skrll * T: 1=touched 0=not touched
398 1.2.2.2 skrll * A: bits of axis A position, MSB to LSB
399 1.2.2.2 skrll * B: bits of axis B position, MSB to LSB
400 1.2.2.2 skrll *
401 1.2.2.2 skrll * For the unit I have, A = Y and B = X.
402 1.2.2.2 skrll * I don't know if units exist with A=X and B=Y,
403 1.2.2.2 skrll * if so we'll cross that bridge when we come to it.
404 1.2.2.2 skrll *
405 1.2.2.2 skrll * The controller sends a stream of T=1 events while the
406 1.2.2.2 skrll * panel is touched, followed by a single T=0 event.
407 1.2.2.2 skrll *
408 1.2.2.2 skrll */
409 1.2.2.2 skrll
410 1.2.2.2 skrll x = (p[3] << 7) | p[4];
411 1.2.2.2 skrll y = (p[1] << 7) | p[2];
412 1.2.2.2 skrll
413 1.2.2.2 skrll tpcalib_trans(&sc->sc_tpcalib, x, y, &x, &y);
414 1.2.2.2 skrll
415 1.2.2.2 skrll s = spltty();
416 1.2.2.2 skrll wsmouse_input(sc->sc_wsmousedev, p[0] & 0x01, x, y, 0,
417 1.2.2.2 skrll WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y);
418 1.2.2.2 skrll splx(s);
419 1.2.2.2 skrll }
420 1.2.2.2 skrll }
421