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