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 | CTLFLAG_MPSAFE, 0, 69 "USB uep"); 70 SYSCTL_INT(_hw_usb_uep, OID_AUTO, debug, CTLFLAG_RWTUN, 71 &uep_debug, 0, "Debug level"); 72 #endif 73 74 #define UEP_MAX_X 2047 75 #define UEP_MAX_Y 2047 76 77 #define UEP_DOWN 0x01 78 #define UEP_PACKET_LEN_MAX 16 79 #define UEP_PACKET_LEN_REPORT 5 80 #define UEP_PACKET_LEN_REPORT2 6 81 #define UEP_PACKET_DIAG 0x0a 82 #define UEP_PACKET_REPORT_MASK 0xe0 83 #define UEP_PACKET_REPORT 0x80 84 #define UEP_PACKET_REPORT_PRESSURE 0xc0 85 #define UEP_PACKET_REPORT_PLAYER 0xa0 86 #define UEP_PACKET_LEN_MASK 87 88 #define UEP_FIFO_BUF_SIZE 8 /* bytes */ 89 #define UEP_FIFO_QUEUE_MAXLEN 50 /* units */ 90 91 enum { 92 UEP_INTR_DT, 93 UEP_N_TRANSFER, 94 }; 95 96 struct uep_softc { 97 struct mtx mtx; 98 99 struct usb_xfer *xfer[UEP_N_TRANSFER]; 100 #ifdef EVDEV_SUPPORT 101 struct evdev_dev *evdev; 102 #else 103 struct usb_fifo_sc fifo; 104 105 u_int pollrate; 106 u_int state; 107 #define UEP_ENABLED 0x01 108 #endif 109 110 /* Reassembling buffer. */ 111 u_char buf[UEP_PACKET_LEN_MAX]; 112 uint8_t buf_len; 113 }; 114 115 static usb_callback_t uep_intr_callback; 116 117 static device_probe_t uep_probe; 118 static device_attach_t uep_attach; 119 static device_detach_t uep_detach; 120 121 #ifdef EVDEV_SUPPORT 122 123 static evdev_open_t uep_ev_open; 124 static evdev_close_t uep_ev_close; 125 126 static const struct evdev_methods uep_evdev_methods = { 127 .ev_open = &uep_ev_open, 128 .ev_close = &uep_ev_close, 129 }; 130 131 #else /* !EVDEV_SUPPORT */ 132 133 static usb_fifo_cmd_t uep_start_read; 134 static usb_fifo_cmd_t uep_stop_read; 135 static usb_fifo_open_t uep_open; 136 static usb_fifo_close_t uep_close; 137 138 static void uep_put_queue(struct uep_softc *, u_char *); 139 140 static struct usb_fifo_methods uep_fifo_methods = { 141 .f_open = &uep_open, 142 .f_close = &uep_close, 143 .f_start_read = &uep_start_read, 144 .f_stop_read = &uep_stop_read, 145 .basename[0] = "uep", 146 }; 147 #endif /* !EVDEV_SUPPORT */ 148 149 static int 150 get_pkt_len(u_char *buf) 151 { 152 if (buf[0] == UEP_PACKET_DIAG) { 153 int len; 154 155 len = buf[1] + 2; 156 if (len > UEP_PACKET_LEN_MAX) { 157 DPRINTF("bad packet len %u\n", len); 158 return (UEP_PACKET_LEN_MAX); 159 } 160 161 return (len); 162 } 163 164 switch (buf[0] & UEP_PACKET_REPORT_MASK) { 165 case UEP_PACKET_REPORT: 166 return (UEP_PACKET_LEN_REPORT); 167 case UEP_PACKET_REPORT_PRESSURE: 168 case UEP_PACKET_REPORT_PLAYER: 169 case UEP_PACKET_REPORT_PRESSURE | UEP_PACKET_REPORT_PLAYER: 170 return (UEP_PACKET_LEN_REPORT2); 171 default: 172 DPRINTF("bad packet len 0\n"); 173 return (0); 174 } 175 } 176 177 static void 178 uep_process_pkt(struct uep_softc *sc, u_char *buf) 179 { 180 int32_t x, y; 181 #ifdef EVDEV_SUPPORT 182 int touch; 183 #endif 184 185 if ((buf[0] & 0xFE) != 0x80) { 186 DPRINTF("bad input packet format 0x%.2x\n", buf[0]); 187 return; 188 } 189 190 /* 191 * Packet format is 5 bytes: 192 * 193 * 1000000T 194 * 0000AAAA 195 * 0AAAAAAA 196 * 0000BBBB 197 * 0BBBBBBB 198 * 199 * T: 1=touched 0=not touched 200 * A: bits of axis A position, MSB to LSB 201 * B: bits of axis B position, MSB to LSB 202 * 203 * For the unit I have, which is CTF1020-S from CarTFT.com, 204 * A = X and B = Y. But in NetBSD uep(4) it is other way round :) 205 * 206 * The controller sends a stream of T=1 events while the 207 * panel is touched, followed by a single T=0 event. 208 * 209 */ 210 211 x = (buf[1] << 7) | buf[2]; 212 y = (buf[3] << 7) | buf[4]; 213 214 DPRINTFN(2, "x %u y %u\n", x, y); 215 216 #ifdef EVDEV_SUPPORT 217 touch = buf[0] & (1 << 0); 218 if (touch) { 219 evdev_push_abs(sc->evdev, ABS_X, x); 220 evdev_push_abs(sc->evdev, ABS_Y, y); 221 } 222 evdev_push_key(sc->evdev, BTN_TOUCH, touch); 223 evdev_sync(sc->evdev); 224 #else 225 uep_put_queue(sc, buf); 226 #endif 227 } 228 229 static void 230 uep_intr_callback(struct usb_xfer *xfer, usb_error_t error) 231 { 232 struct uep_softc *sc = usbd_xfer_softc(xfer); 233 int len; 234 235 usbd_xfer_status(xfer, &len, NULL, NULL, NULL); 236 237 switch (USB_GET_STATE(xfer)) { 238 case USB_ST_TRANSFERRED: 239 { 240 struct usb_page_cache *pc; 241 u_char buf[17], *p; 242 int pkt_len; 243 244 if (len > (int)sizeof(buf)) { 245 DPRINTF("bad input length %d\n", len); 246 goto tr_setup; 247 } 248 249 pc = usbd_xfer_get_frame(xfer, 0); 250 usbd_copy_out(pc, 0, buf, len); 251 252 /* 253 * The below code mimics Linux a lot. I don't know 254 * why NetBSD reads complete packets, but we need 255 * to reassamble 'em like Linux does (tries?). 256 */ 257 if (sc->buf_len > 0) { 258 int res; 259 260 if (sc->buf_len == 1) 261 sc->buf[1] = buf[0]; 262 263 if ((pkt_len = get_pkt_len(sc->buf)) == 0) 264 goto tr_setup; 265 266 res = pkt_len - sc->buf_len; 267 memcpy(sc->buf + sc->buf_len, buf, res); 268 uep_process_pkt(sc, sc->buf); 269 sc->buf_len = 0; 270 271 p = buf + res; 272 len -= res; 273 } else 274 p = buf; 275 276 if (len == 1) { 277 sc->buf[0] = buf[0]; 278 sc->buf_len = 1; 279 280 goto tr_setup; 281 } 282 283 while (len > 0) { 284 if ((pkt_len = get_pkt_len(p)) == 0) 285 goto tr_setup; 286 287 /* full packet: process */ 288 if (pkt_len <= len) { 289 uep_process_pkt(sc, p); 290 } else { 291 /* incomplete packet: save in buffer */ 292 memcpy(sc->buf, p, len); 293 sc->buf_len = len; 294 } 295 p += pkt_len; 296 len -= pkt_len; 297 } 298 } 299 case USB_ST_SETUP: 300 tr_setup: 301 #ifndef EVDEV_SUPPORT 302 /* check if we can put more data into the FIFO */ 303 if (usb_fifo_put_bytes_max(sc->fifo.fp[USB_FIFO_RX]) == 0) 304 break; 305 #endif 306 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); 307 usbd_transfer_submit(xfer); 308 break; 309 310 default: 311 if (error != USB_ERR_CANCELLED) { 312 /* try clear stall first */ 313 usbd_xfer_set_stall(xfer); 314 goto tr_setup; 315 } 316 break; 317 } 318 } 319 320 static const struct usb_config uep_config[UEP_N_TRANSFER] = { 321 [UEP_INTR_DT] = { 322 .type = UE_INTERRUPT, 323 .endpoint = UE_ADDR_ANY, 324 .direction = UE_DIR_IN, 325 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 326 .bufsize = 0, /* use wMaxPacketSize */ 327 .callback = &uep_intr_callback, 328 }, 329 }; 330 331 static const STRUCT_USB_HOST_ID uep_devs[] = { 332 {USB_VPI(USB_VENDOR_EGALAX, USB_PRODUCT_EGALAX_TPANEL, 0)}, 333 {USB_VPI(USB_VENDOR_EGALAX, USB_PRODUCT_EGALAX_TPANEL2, 0)}, 334 {USB_VPI(USB_VENDOR_EGALAX2, USB_PRODUCT_EGALAX2_TPANEL, 0)}, 335 }; 336 337 static int 338 uep_probe(device_t dev) 339 { 340 struct usb_attach_arg *uaa = device_get_ivars(dev); 341 342 if (uaa->usb_mode != USB_MODE_HOST) 343 return (ENXIO); 344 if (uaa->info.bConfigIndex != 0) 345 return (ENXIO); 346 if (uaa->info.bIfaceIndex != 0) 347 return (ENXIO); 348 349 return (usbd_lookup_id_by_uaa(uep_devs, sizeof(uep_devs), uaa)); 350 } 351 352 static int 353 uep_attach(device_t dev) 354 { 355 struct usb_attach_arg *uaa = device_get_ivars(dev); 356 struct uep_softc *sc = device_get_softc(dev); 357 int error; 358 359 device_set_usb_desc(dev); 360 361 mtx_init(&sc->mtx, "uep lock", NULL, MTX_DEF); 362 363 error = usbd_transfer_setup(uaa->device, &uaa->info.bIfaceIndex, 364 sc->xfer, uep_config, UEP_N_TRANSFER, sc, &sc->mtx); 365 366 if (error) { 367 DPRINTF("usbd_transfer_setup error=%s\n", usbd_errstr(error)); 368 goto detach; 369 } 370 371 #ifdef EVDEV_SUPPORT 372 sc->evdev = evdev_alloc(); 373 evdev_set_name(sc->evdev, device_get_desc(dev)); 374 evdev_set_phys(sc->evdev, device_get_nameunit(dev)); 375 evdev_set_id(sc->evdev, BUS_USB, uaa->info.idVendor, 376 uaa->info.idProduct, 0); 377 evdev_set_serial(sc->evdev, usb_get_serial(uaa->device)); 378 evdev_set_methods(sc->evdev, sc, &uep_evdev_methods); 379 evdev_support_prop(sc->evdev, INPUT_PROP_DIRECT); 380 evdev_support_event(sc->evdev, EV_SYN); 381 evdev_support_event(sc->evdev, EV_ABS); 382 evdev_support_event(sc->evdev, EV_KEY); 383 evdev_support_key(sc->evdev, BTN_TOUCH); 384 evdev_support_abs(sc->evdev, ABS_X, 0, UEP_MAX_X, 0, 0, 0); 385 evdev_support_abs(sc->evdev, ABS_Y, 0, UEP_MAX_Y, 0, 0, 0); 386 387 error = evdev_register_mtx(sc->evdev, &sc->mtx); 388 if (error) { 389 DPRINTF("evdev_register_mtx error=%s\n", usbd_errstr(error)); 390 goto detach; 391 } 392 #else /* !EVDEV_SUPPORT */ 393 error = usb_fifo_attach(uaa->device, sc, &sc->mtx, &uep_fifo_methods, 394 &sc->fifo, device_get_unit(dev), -1, uaa->info.bIfaceIndex, 395 UID_ROOT, GID_OPERATOR, 0644); 396 397 if (error) { 398 DPRINTF("usb_fifo_attach error=%s\n", usbd_errstr(error)); 399 goto detach; 400 } 401 #endif /* !EVDEV_SUPPORT */ 402 403 sc->buf_len = 0; 404 405 return (0); 406 407 detach: 408 uep_detach(dev); 409 410 return (ENOMEM); /* XXX */ 411 } 412 413 static int 414 uep_detach(device_t dev) 415 { 416 struct uep_softc *sc = device_get_softc(dev); 417 418 #ifdef EVDEV_SUPPORT 419 evdev_free(sc->evdev); 420 #else 421 usb_fifo_detach(&sc->fifo); 422 #endif 423 424 usbd_transfer_unsetup(sc->xfer, UEP_N_TRANSFER); 425 426 mtx_destroy(&sc->mtx); 427 428 return (0); 429 } 430 431 #ifdef EVDEV_SUPPORT 432 433 static int 434 uep_ev_close(struct evdev_dev *evdev) 435 { 436 struct uep_softc *sc = evdev_get_softc(evdev); 437 438 mtx_assert(&sc->mtx, MA_OWNED); 439 usbd_transfer_stop(sc->xfer[UEP_INTR_DT]); 440 441 return (0); 442 } 443 444 static int 445 uep_ev_open(struct evdev_dev *evdev) 446 { 447 struct uep_softc *sc = evdev_get_softc(evdev); 448 449 mtx_assert(&sc->mtx, MA_OWNED); 450 usbd_transfer_start(sc->xfer[UEP_INTR_DT]); 451 452 return (0); 453 } 454 455 #else /* !EVDEV_SUPPORT */ 456 457 static void 458 uep_start_read(struct usb_fifo *fifo) 459 { 460 struct uep_softc *sc = usb_fifo_softc(fifo); 461 u_int rate; 462 463 if ((rate = sc->pollrate) > 1000) 464 rate = 1000; 465 466 if (rate > 0 && sc->xfer[UEP_INTR_DT] != NULL) { 467 usbd_transfer_stop(sc->xfer[UEP_INTR_DT]); 468 usbd_xfer_set_interval(sc->xfer[UEP_INTR_DT], 1000 / rate); 469 sc->pollrate = 0; 470 } 471 472 usbd_transfer_start(sc->xfer[UEP_INTR_DT]); 473 } 474 475 static void 476 uep_stop_read(struct usb_fifo *fifo) 477 { 478 struct uep_softc *sc = usb_fifo_softc(fifo); 479 480 usbd_transfer_stop(sc->xfer[UEP_INTR_DT]); 481 } 482 483 static void 484 uep_put_queue(struct uep_softc *sc, u_char *buf) 485 { 486 usb_fifo_put_data_linear(sc->fifo.fp[USB_FIFO_RX], buf, 487 UEP_PACKET_LEN_REPORT, 1); 488 } 489 490 static int 491 uep_open(struct usb_fifo *fifo, int fflags) 492 { 493 if (fflags & FREAD) { 494 struct uep_softc *sc = usb_fifo_softc(fifo); 495 496 if (sc->state & UEP_ENABLED) 497 return (EBUSY); 498 if (usb_fifo_alloc_buffer(fifo, UEP_FIFO_BUF_SIZE, 499 UEP_FIFO_QUEUE_MAXLEN)) 500 return (ENOMEM); 501 502 sc->state |= UEP_ENABLED; 503 } 504 505 return (0); 506 } 507 508 static void 509 uep_close(struct usb_fifo *fifo, int fflags) 510 { 511 if (fflags & FREAD) { 512 struct uep_softc *sc = usb_fifo_softc(fifo); 513 514 sc->state &= ~(UEP_ENABLED); 515 usb_fifo_free_buffer(fifo); 516 } 517 } 518 #endif /* !EVDEV_SUPPORT */ 519 520 static devclass_t uep_devclass; 521 522 static device_method_t uep_methods[] = { 523 DEVMETHOD(device_probe, uep_probe), 524 DEVMETHOD(device_attach, uep_attach), 525 DEVMETHOD(device_detach, uep_detach), 526 { 0, 0 }, 527 }; 528 529 static driver_t uep_driver = { 530 .name = "uep", 531 .methods = uep_methods, 532 .size = sizeof(struct uep_softc), 533 }; 534 535 DRIVER_MODULE(uep, uhub, uep_driver, uep_devclass, NULL, NULL); 536 MODULE_DEPEND(uep, usb, 1, 1, 1); 537 #ifdef EVDEV_SUPPORT 538 MODULE_DEPEND(uep, evdev, 1, 1, 1); 539 #endif 540 MODULE_VERSION(uep, 1); 541 USB_PNP_HOST_INFO(uep_devs); 542