xref: /freebsd/sys/dev/usb/input/uep.c (revision 2c9a9dfc187d171de6b92654d71b977f067ed641)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright 2010, Gleb Smirnoff <glebius@FreeBSD.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30 
31 /*
32  *  http://www.eeti.com.tw/pdf/Software%20Programming%20Guide_v2.0.pdf
33  */
34 
35 #include "opt_evdev.h"
36 
37 #include <sys/param.h>
38 #include <sys/bus.h>
39 #include <sys/callout.h>
40 #include <sys/conf.h>
41 #include <sys/kernel.h>
42 #include <sys/lock.h>
43 #include <sys/module.h>
44 #include <sys/mutex.h>
45 #include <sys/sysctl.h>
46 #include <sys/systm.h>
47 
48 #include <dev/usb/usb.h>
49 #include <dev/usb/usbdi.h>
50 #include <dev/usb/usbdi_util.h>
51 #include <dev/usb/usbhid.h>
52 #include "usbdevs.h"
53 
54 #ifdef EVDEV_SUPPORT
55 #include <dev/evdev/input.h>
56 #include <dev/evdev/evdev.h>
57 #else
58 #include <sys/ioccom.h>
59 #include <sys/fcntl.h>
60 #endif
61 
62 #define USB_DEBUG_VAR uep_debug
63 #include <dev/usb/usb_debug.h>
64 
65 #ifdef USB_DEBUG
66 static int uep_debug = 0;
67 
68 static SYSCTL_NODE(_hw_usb, OID_AUTO, uep, CTLFLAG_RW, 0, "USB uep");
69 SYSCTL_INT(_hw_usb_uep, OID_AUTO, debug, CTLFLAG_RWTUN,
70     &uep_debug, 0, "Debug level");
71 #endif
72 
73 #define UEP_MAX_X		2047
74 #define UEP_MAX_Y		2047
75 
76 #define UEP_DOWN		0x01
77 #define UEP_PACKET_LEN_MAX	16
78 #define UEP_PACKET_LEN_REPORT	5
79 #define UEP_PACKET_LEN_REPORT2	6
80 #define UEP_PACKET_DIAG		0x0a
81 #define UEP_PACKET_REPORT_MASK		0xe0
82 #define UEP_PACKET_REPORT		0x80
83 #define UEP_PACKET_REPORT_PRESSURE	0xc0
84 #define UEP_PACKET_REPORT_PLAYER	0xa0
85 #define	UEP_PACKET_LEN_MASK
86 
87 #define UEP_FIFO_BUF_SIZE	8	/* bytes */
88 #define UEP_FIFO_QUEUE_MAXLEN	50	/* units */
89 
90 enum {
91 	UEP_INTR_DT,
92 	UEP_N_TRANSFER,
93 };
94 
95 struct uep_softc {
96 	struct mtx mtx;
97 
98 	struct usb_xfer *xfer[UEP_N_TRANSFER];
99 #ifdef EVDEV_SUPPORT
100 	struct evdev_dev *evdev;
101 #else
102 	struct usb_fifo_sc fifo;
103 
104 	u_int		pollrate;
105 	u_int		state;
106 #define UEP_ENABLED	0x01
107 #endif
108 
109 	/* Reassembling buffer. */
110 	u_char		buf[UEP_PACKET_LEN_MAX];
111 	uint8_t		buf_len;
112 };
113 
114 static usb_callback_t uep_intr_callback;
115 
116 static device_probe_t	uep_probe;
117 static device_attach_t	uep_attach;
118 static device_detach_t	uep_detach;
119 
120 #ifdef EVDEV_SUPPORT
121 
122 static evdev_open_t	uep_ev_open;
123 static evdev_close_t	uep_ev_close;
124 
125 static const struct evdev_methods uep_evdev_methods = {
126 	.ev_open = &uep_ev_open,
127 	.ev_close = &uep_ev_close,
128 };
129 
130 #else /* !EVDEV_SUPPORT */
131 
132 static usb_fifo_cmd_t	uep_start_read;
133 static usb_fifo_cmd_t	uep_stop_read;
134 static usb_fifo_open_t	uep_open;
135 static usb_fifo_close_t	uep_close;
136 
137 static void uep_put_queue(struct uep_softc *, u_char *);
138 
139 static struct usb_fifo_methods uep_fifo_methods = {
140 	.f_open = &uep_open,
141 	.f_close = &uep_close,
142 	.f_start_read = &uep_start_read,
143 	.f_stop_read = &uep_stop_read,
144 	.basename[0] = "uep",
145 };
146 #endif /* !EVDEV_SUPPORT */
147 
148 static int
149 get_pkt_len(u_char *buf)
150 {
151 	if (buf[0] == UEP_PACKET_DIAG) {
152 		int len;
153 
154 		len = buf[1] + 2;
155 		if (len > UEP_PACKET_LEN_MAX) {
156 			DPRINTF("bad packet len %u\n", len);
157 			return (UEP_PACKET_LEN_MAX);
158 		}
159 
160 		return (len);
161 	}
162 
163 	switch (buf[0] & UEP_PACKET_REPORT_MASK) {
164 	case UEP_PACKET_REPORT:
165 		return (UEP_PACKET_LEN_REPORT);
166 	case UEP_PACKET_REPORT_PRESSURE:
167 	case UEP_PACKET_REPORT_PLAYER:
168 	case UEP_PACKET_REPORT_PRESSURE | UEP_PACKET_REPORT_PLAYER:
169 		return (UEP_PACKET_LEN_REPORT2);
170 	default:
171 		DPRINTF("bad packet len 0\n");
172 		return (0);
173 	}
174 }
175 
176 static void
177 uep_process_pkt(struct uep_softc *sc, u_char *buf)
178 {
179 	int32_t x, y;
180 #ifdef EVDEV_SUPPORT
181 	int touch;
182 #endif
183 
184 	if ((buf[0] & 0xFE) != 0x80) {
185 		DPRINTF("bad input packet format 0x%.2x\n", buf[0]);
186 		return;
187 	}
188 
189 	/*
190 	 * Packet format is 5 bytes:
191 	 *
192 	 * 1000000T
193 	 * 0000AAAA
194 	 * 0AAAAAAA
195 	 * 0000BBBB
196 	 * 0BBBBBBB
197 	 *
198 	 * T: 1=touched 0=not touched
199 	 * A: bits of axis A position, MSB to LSB
200 	 * B: bits of axis B position, MSB to LSB
201 	 *
202 	 * For the unit I have, which is CTF1020-S from CarTFT.com,
203 	 * A = X and B = Y. But in NetBSD uep(4) it is other way round :)
204 	 *
205 	 * The controller sends a stream of T=1 events while the
206 	 * panel is touched, followed by a single T=0 event.
207 	 *
208 	 */
209 
210 	x = (buf[1] << 7) | buf[2];
211 	y = (buf[3] << 7) | buf[4];
212 
213 	DPRINTFN(2, "x %u y %u\n", x, y);
214 
215 #ifdef EVDEV_SUPPORT
216 	touch = buf[0] & (1 << 0);
217 	if (touch) {
218 		evdev_push_abs(sc->evdev, ABS_X, x);
219 		evdev_push_abs(sc->evdev, ABS_Y, y);
220 	}
221 	evdev_push_key(sc->evdev, BTN_TOUCH, touch);
222 	evdev_sync(sc->evdev);
223 #else
224 	uep_put_queue(sc, buf);
225 #endif
226 }
227 
228 static void
229 uep_intr_callback(struct usb_xfer *xfer, usb_error_t error)
230 {
231 	struct uep_softc *sc = usbd_xfer_softc(xfer);
232 	int len;
233 
234 	usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
235 
236 	switch (USB_GET_STATE(xfer)) {
237 	case USB_ST_TRANSFERRED:
238 	    {
239 		struct usb_page_cache *pc;
240 		u_char buf[17], *p;
241 		int pkt_len;
242 
243 		if (len > (int)sizeof(buf)) {
244 			DPRINTF("bad input length %d\n", len);
245 			goto tr_setup;
246 		}
247 
248 		pc = usbd_xfer_get_frame(xfer, 0);
249 		usbd_copy_out(pc, 0, buf, len);
250 
251 		/*
252 		 * The below code mimics Linux a lot. I don't know
253 		 * why NetBSD reads complete packets, but we need
254 		 * to reassamble 'em like Linux does (tries?).
255 		 */
256 		if (sc->buf_len > 0) {
257 			int res;
258 
259 			if (sc->buf_len == 1)
260 				sc->buf[1] = buf[0];
261 
262 			if ((pkt_len = get_pkt_len(sc->buf)) == 0)
263 				goto tr_setup;
264 
265 			res = pkt_len - sc->buf_len;
266 			memcpy(sc->buf + sc->buf_len, buf, res);
267 			uep_process_pkt(sc, sc->buf);
268 			sc->buf_len = 0;
269 
270 			p = buf + res;
271 			len -= res;
272 		} else
273 			p = buf;
274 
275 		if (len == 1) {
276 			sc->buf[0] = buf[0];
277 			sc->buf_len = 1;
278 
279 			goto tr_setup;
280 		}
281 
282 		while (len > 0) {
283 			if ((pkt_len = get_pkt_len(p)) == 0)
284 				goto tr_setup;
285 
286 			/* full packet: process */
287 			if (pkt_len <= len) {
288 				uep_process_pkt(sc, p);
289 			} else {
290 				/* incomplete packet: save in buffer */
291 				memcpy(sc->buf, p, len);
292 				sc->buf_len = len;
293 			}
294 			p += pkt_len;
295 			len -= pkt_len;
296 		}
297 	    }
298 	case USB_ST_SETUP:
299 	tr_setup:
300 #ifndef EVDEV_SUPPORT
301 		/* check if we can put more data into the FIFO */
302 		if (usb_fifo_put_bytes_max(sc->fifo.fp[USB_FIFO_RX]) == 0)
303 			break;
304 #endif
305 		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
306 		usbd_transfer_submit(xfer);
307 		break;
308 
309 	default:
310 		if (error != USB_ERR_CANCELLED) {
311 			/* try clear stall first */
312 			usbd_xfer_set_stall(xfer);
313 			goto tr_setup;
314 		}
315 		break;
316 	}
317 }
318 
319 static const struct usb_config uep_config[UEP_N_TRANSFER] = {
320 	[UEP_INTR_DT] = {
321 		.type = UE_INTERRUPT,
322 		.endpoint = UE_ADDR_ANY,
323 		.direction = UE_DIR_IN,
324 		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
325 		.bufsize = 0,   /* use wMaxPacketSize */
326 		.callback = &uep_intr_callback,
327 	},
328 };
329 
330 static const STRUCT_USB_HOST_ID uep_devs[] = {
331 	{USB_VPI(USB_VENDOR_EGALAX, USB_PRODUCT_EGALAX_TPANEL, 0)},
332 	{USB_VPI(USB_VENDOR_EGALAX, USB_PRODUCT_EGALAX_TPANEL2, 0)},
333 	{USB_VPI(USB_VENDOR_EGALAX2, USB_PRODUCT_EGALAX2_TPANEL, 0)},
334 };
335 
336 static int
337 uep_probe(device_t dev)
338 {
339 	struct usb_attach_arg *uaa = device_get_ivars(dev);
340 
341 	if (uaa->usb_mode != USB_MODE_HOST)
342 		return (ENXIO);
343 	if (uaa->info.bConfigIndex != 0)
344 		return (ENXIO);
345 	if (uaa->info.bIfaceIndex != 0)
346 		return (ENXIO);
347 
348 	return (usbd_lookup_id_by_uaa(uep_devs, sizeof(uep_devs), uaa));
349 }
350 
351 static int
352 uep_attach(device_t dev)
353 {
354 	struct usb_attach_arg *uaa = device_get_ivars(dev);
355 	struct uep_softc *sc = device_get_softc(dev);
356 	int error;
357 
358 	device_set_usb_desc(dev);
359 
360 	mtx_init(&sc->mtx, "uep lock", NULL, MTX_DEF);
361 
362 	error = usbd_transfer_setup(uaa->device, &uaa->info.bIfaceIndex,
363 	    sc->xfer, uep_config, UEP_N_TRANSFER, sc, &sc->mtx);
364 
365 	if (error) {
366 		DPRINTF("usbd_transfer_setup error=%s\n", usbd_errstr(error));
367 		goto detach;
368 	}
369 
370 #ifdef EVDEV_SUPPORT
371 	sc->evdev = evdev_alloc();
372 	evdev_set_name(sc->evdev, device_get_desc(dev));
373 	evdev_set_phys(sc->evdev, device_get_nameunit(dev));
374 	evdev_set_id(sc->evdev, BUS_USB, uaa->info.idVendor,
375 	    uaa->info.idProduct, 0);
376 	evdev_set_serial(sc->evdev, usb_get_serial(uaa->device));
377 	evdev_set_methods(sc->evdev, sc, &uep_evdev_methods);
378 	evdev_support_prop(sc->evdev, INPUT_PROP_DIRECT);
379 	evdev_support_event(sc->evdev, EV_SYN);
380 	evdev_support_event(sc->evdev, EV_ABS);
381 	evdev_support_event(sc->evdev, EV_KEY);
382 	evdev_support_key(sc->evdev, BTN_TOUCH);
383 	evdev_support_abs(sc->evdev, ABS_X, 0, 0, UEP_MAX_X, 0, 0, 0);
384 	evdev_support_abs(sc->evdev, ABS_Y, 0, 0, UEP_MAX_Y, 0, 0, 0);
385 
386 	error = evdev_register_mtx(sc->evdev, &sc->mtx);
387 	if (error) {
388 		DPRINTF("evdev_register_mtx error=%s\n", usbd_errstr(error));
389 		goto detach;
390 	}
391 #else /* !EVDEV_SUPPORT */
392 	error = usb_fifo_attach(uaa->device, sc, &sc->mtx, &uep_fifo_methods,
393 	    &sc->fifo, device_get_unit(dev), -1, uaa->info.bIfaceIndex,
394 	    UID_ROOT, GID_OPERATOR, 0644);
395 
396         if (error) {
397 		DPRINTF("usb_fifo_attach error=%s\n", usbd_errstr(error));
398                 goto detach;
399         }
400 #endif /* !EVDEV_SUPPORT */
401 
402 	sc->buf_len = 0;
403 
404 	return (0);
405 
406 detach:
407 	uep_detach(dev);
408 
409 	return (ENOMEM); /* XXX */
410 }
411 
412 static int
413 uep_detach(device_t dev)
414 {
415 	struct uep_softc *sc = device_get_softc(dev);
416 
417 #ifdef EVDEV_SUPPORT
418 	evdev_free(sc->evdev);
419 #else
420 	usb_fifo_detach(&sc->fifo);
421 #endif
422 
423 	usbd_transfer_unsetup(sc->xfer, UEP_N_TRANSFER);
424 
425 	mtx_destroy(&sc->mtx);
426 
427 	return (0);
428 }
429 
430 #ifdef EVDEV_SUPPORT
431 
432 static int
433 uep_ev_close(struct evdev_dev *evdev)
434 {
435 	struct uep_softc *sc = evdev_get_softc(evdev);
436 
437 	mtx_assert(&sc->mtx, MA_OWNED);
438 	usbd_transfer_stop(sc->xfer[UEP_INTR_DT]);
439 
440 	return (0);
441 }
442 
443 static int
444 uep_ev_open(struct evdev_dev *evdev)
445 {
446 	struct uep_softc *sc = evdev_get_softc(evdev);
447 
448 	mtx_assert(&sc->mtx, MA_OWNED);
449 	usbd_transfer_start(sc->xfer[UEP_INTR_DT]);
450 
451 	return (0);
452 }
453 
454 #else /* !EVDEV_SUPPORT */
455 
456 static void
457 uep_start_read(struct usb_fifo *fifo)
458 {
459 	struct uep_softc *sc = usb_fifo_softc(fifo);
460 	u_int rate;
461 
462 	if ((rate = sc->pollrate) > 1000)
463 		rate = 1000;
464 
465 	if (rate > 0 && sc->xfer[UEP_INTR_DT] != NULL) {
466 		usbd_transfer_stop(sc->xfer[UEP_INTR_DT]);
467 		usbd_xfer_set_interval(sc->xfer[UEP_INTR_DT], 1000 / rate);
468 		sc->pollrate = 0;
469 	}
470 
471 	usbd_transfer_start(sc->xfer[UEP_INTR_DT]);
472 }
473 
474 static void
475 uep_stop_read(struct usb_fifo *fifo)
476 {
477 	struct uep_softc *sc = usb_fifo_softc(fifo);
478 
479 	usbd_transfer_stop(sc->xfer[UEP_INTR_DT]);
480 }
481 
482 static void
483 uep_put_queue(struct uep_softc *sc, u_char *buf)
484 {
485 	usb_fifo_put_data_linear(sc->fifo.fp[USB_FIFO_RX], buf,
486 	    UEP_PACKET_LEN_REPORT, 1);
487 }
488 
489 static int
490 uep_open(struct usb_fifo *fifo, int fflags)
491 {
492 	if (fflags & FREAD) {
493 		struct uep_softc *sc = usb_fifo_softc(fifo);
494 
495 		if (sc->state & UEP_ENABLED)
496 			return (EBUSY);
497 		if (usb_fifo_alloc_buffer(fifo, UEP_FIFO_BUF_SIZE,
498 		    UEP_FIFO_QUEUE_MAXLEN))
499 			return (ENOMEM);
500 
501 		sc->state |= UEP_ENABLED;
502 	}
503 
504 	return (0);
505 }
506 
507 static void
508 uep_close(struct usb_fifo *fifo, int fflags)
509 {
510 	if (fflags & FREAD) {
511 		struct uep_softc *sc = usb_fifo_softc(fifo);
512 
513 		sc->state &= ~(UEP_ENABLED);
514 		usb_fifo_free_buffer(fifo);
515 	}
516 }
517 #endif /* !EVDEV_SUPPORT */
518 
519 static devclass_t uep_devclass;
520 
521 static device_method_t uep_methods[] = {
522 	DEVMETHOD(device_probe, uep_probe),
523        	DEVMETHOD(device_attach, uep_attach),
524 	DEVMETHOD(device_detach, uep_detach),
525 	{ 0, 0 },
526 };
527 
528 static driver_t uep_driver = {
529 	.name = "uep",
530 	.methods = uep_methods,
531 	.size = sizeof(struct uep_softc),
532 };
533 
534 DRIVER_MODULE(uep, uhub, uep_driver, uep_devclass, NULL, NULL);
535 MODULE_DEPEND(uep, usb, 1, 1, 1);
536 #ifdef EVDEV_SUPPORT
537 MODULE_DEPEND(uep, evdev, 1, 1, 1);
538 #endif
539 MODULE_VERSION(uep, 1);
540 USB_PNP_HOST_INFO(uep_devs);
541