Index: share/man/man4/uep.4 =================================================================== --- share/man/man4/uep.4 +++ share/man/man4/uep.4 @@ -44,6 +44,13 @@ .Bd -literal -offset indent uep_load="YES" .Ed +.Pp +To compile this driver with evdev support enabled, place the +following lines into your kernel configuration file: +.Bd -ragged -offset indent +.Cd "options EVDEV_SUPPORT" +.Cd "device evdev" +.Ed .Sh DESCRIPTION The .Nm @@ -51,21 +58,32 @@ .Pp The driver is stub. It just probes and attaches to USB device, creates device entry -and feeds reassembled packets from the hardware to it. +and feeds reassembled packets from the hardware to it. Depending on +compile\-time kernel options it supports one of the next operation +modes: native or evdev. They are are mutually exclusive. .Pp To get mouse working in -.Xr X 7 , -one needs to install +.Xr X 7 +in native mode, one needs to install .Pa ports/x11-drivers/xf86-input-egalax . +.Pp +To get mouse working in +.Xr X 7 +in evdev mode, one needs to install +.Pa ports/x11-drivers/xf86-input-evdev . .Sh FILES .Nm creates a blocking pseudo\-device file, -.Pa /dev/uep0 . +.Pa /dev/uep0 +in native mode or +.Pa /dev/input/eventN +in evdev mode. .Sh SEE ALSO .Xr usb 4 , .Xr loader.conf 5 , .Xr xorg.conf 5 Pq Pa ports/x11/xorg , -.Xr egalax 4 Pq Pa ports/x11-drivers/xf86-input-egalax . +.Xr egalax 4 Pq Pa ports/x11-drivers/xf86-input-egalax , +.Xr evdev 4 Pq Pa ports/x11-drivers/xf86-input-evdev . .Sh AUTHORS .An -nosplit The Index: sys/dev/usb/input/uep.c =================================================================== --- sys/dev/usb/input/uep.c +++ sys/dev/usb/input/uep.c @@ -30,6 +30,8 @@ * http://www.eeti.com.tw/pdf/Software%20Programming%20Guide_v2.0.pdf */ +#include "opt_evdev.h" + #include #include #include @@ -47,9 +49,14 @@ #include #include "usbdevs.h" +#ifdef EVDEV_SUPPORT +#include +#include +#else #include #include #include +#endif #define USB_DEBUG_VAR uep_debug #include @@ -64,6 +71,11 @@ #define UEP_MAX_X 2047 #define UEP_MAX_Y 2047 +#define UEP_SIZE_X 222 /* mm */ +#define UEP_SIZE_Y 134 /* mm */ +#define UEP_RES_X (UEP_MAX_X/UEP_SIZE_X) +#define UEP_RES_Y (UEP_MAX_Y/UEP_SIZE_Y) +#define UEP_MAX_P 127 #define UEP_DOWN 0x01 #define UEP_PACKET_LEN_MAX 16 @@ -88,11 +100,15 @@ struct mtx mtx; struct usb_xfer *xfer[UEP_N_TRANSFER]; +#ifdef EVDEV_SUPPORT + struct evdev_dev *evdev; +#else struct usb_fifo_sc fifo; u_int pollrate; u_int state; #define UEP_ENABLED 0x01 +#endif /* Reassembling buffer. */ u_char buf[UEP_PACKET_LEN_MAX]; @@ -105,6 +121,18 @@ static device_attach_t uep_attach; static device_detach_t uep_detach; +#ifdef EVDEV_SUPPORT + +static evdev_open_t uep_ev_open; +static evdev_close_t uep_ev_close; + +static const struct evdev_methods uep_evdev_methods = { + .ev_open = &uep_ev_open, + .ev_close = &uep_ev_close, +}; + +#else /* !EVDEV_SUPPORT */ + static usb_fifo_cmd_t uep_start_read; static usb_fifo_cmd_t uep_stop_read; static usb_fifo_open_t uep_open; @@ -119,6 +147,7 @@ .f_stop_read = &uep_stop_read, .basename[0] = "uep", }; +#endif /* !EVDEV_SUPPORT */ static int get_pkt_len(u_char *buf) @@ -152,24 +181,30 @@ uep_process_pkt(struct uep_softc *sc, u_char *buf) { int32_t x, y; +#ifdef EVDEV_SUPPORT + int touch; +#endif - if ((buf[0] & 0xFE) != 0x80) { + if ((buf[0] & 0xBE) != 0x80) { DPRINTF("bad input packet format 0x%.2x\n", buf[0]); return; } /* - * Packet format is 5 bytes: + * Packet format is 5 or 6 bytes: * - * 1000000T + * 1Z00000T * 0000AAAA * 0AAAAAAA * 0000BBBB * 0BBBBBBB + * 0PPPPPPP * * T: 1=touched 0=not touched + * Z: 1=byte5 is pressure information * A: bits of axis A position, MSB to LSB * B: bits of axis B position, MSB to LSB + * P: bits of pressure, MSB to LSB * * For the unit I have, which is CTF1020-S from CarTFT.com, * A = X and B = Y. But in NetBSD uep(4) it is other way round :) @@ -184,7 +219,20 @@ DPRINTFN(2, "x %u y %u\n", x, y); +#ifdef EVDEV_SUPPORT + touch = buf[0] & (1 << 0); + if (touch) { + evdev_push_abs(sc->evdev, ABS_X, x); + evdev_push_abs(sc->evdev, ABS_Y, y); + if ((buf[0] & UEP_PACKET_REPORT_MASK) == + UEP_PACKET_REPORT_PRESSURE) + evdev_push_abs(sc->evdev, ABS_PRESSURE, buf[5]); + } + evdev_push_key(sc->evdev, BTN_TOUCH, touch); + evdev_sync(sc->evdev); +#else uep_put_queue(sc, buf); +#endif } static void @@ -259,12 +307,13 @@ } case USB_ST_SETUP: tr_setup: +#ifndef EVDEV_SUPPORT /* check if we can put more data into the FIFO */ - if (usb_fifo_put_bytes_max(sc->fifo.fp[USB_FIFO_RX]) != 0) { - usbd_xfer_set_frame_len(xfer, 0, - usbd_xfer_max_len(xfer)); - usbd_transfer_submit(xfer); - } + if (usb_fifo_put_bytes_max(sc->fifo.fp[USB_FIFO_RX]) == 0) + break; +#endif + usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); + usbd_transfer_submit(xfer); break; default: @@ -328,6 +377,29 @@ goto detach; } +#ifdef EVDEV_SUPPORT + sc->evdev = evdev_alloc(); + evdev_set_name(sc->evdev, device_get_desc(dev)); + evdev_set_phys(sc->evdev, device_get_nameunit(dev)); + evdev_set_id(sc->evdev, BUS_USB, uaa->info.idVendor, + uaa->info.idProduct, 0); + evdev_set_serial(sc->evdev, usb_get_serial(uaa->device)); + evdev_set_methods(sc->evdev, sc, &uep_evdev_methods); + evdev_support_prop(sc->evdev, INPUT_PROP_DIRECT); + evdev_support_event(sc->evdev, EV_SYN); + evdev_support_event(sc->evdev, EV_ABS); + evdev_support_event(sc->evdev, EV_KEY); + evdev_support_key(sc->evdev, BTN_TOUCH); + evdev_support_abs(sc->evdev, ABS_X, 0, 0, UEP_MAX_X, 0, 0, UEP_RES_X); + evdev_support_abs(sc->evdev, ABS_Y, 0, 0, UEP_MAX_Y, 0, 0, UEP_RES_Y); + evdev_support_abs(sc->evdev, ABS_PRESSURE, 0, 0, UEP_MAX_P, 0, 0, 0); + + error = evdev_register_mtx(sc->evdev, &sc->mtx); + if (error) { + DPRINTF("evdev_register_mtx error=%s\n", usbd_errstr(error)); + goto detach; + } +#else /* !EVDEV_SUPPORT */ error = usb_fifo_attach(uaa->device, sc, &sc->mtx, &uep_fifo_methods, &sc->fifo, device_get_unit(dev), -1, uaa->info.bIfaceIndex, UID_ROOT, GID_OPERATOR, 0644); @@ -336,6 +408,7 @@ DPRINTF("usb_fifo_attach error=%s\n", usbd_errstr(error)); goto detach; } +#endif /* !EVDEV_SUPPORT */ sc->buf_len = 0; @@ -352,7 +425,11 @@ { struct uep_softc *sc = device_get_softc(dev); +#ifdef EVDEV_SUPPORT + evdev_free(sc->evdev); +#else usb_fifo_detach(&sc->fifo); +#endif usbd_transfer_unsetup(sc->xfer, UEP_N_TRANSFER); @@ -361,6 +438,30 @@ return (0); } +#ifdef EVDEV_SUPPORT + +static void +uep_ev_close(struct evdev_dev *evdev, void *ev_softc) +{ + struct uep_softc *sc = (struct uep_softc *)ev_softc; + + mtx_assert(&sc->mtx, MA_OWNED); + usbd_transfer_stop(sc->xfer[UEP_INTR_DT]); +} + +static int +uep_ev_open(struct evdev_dev *evdev, void *ev_softc) +{ + struct uep_softc *sc = (struct uep_softc *)ev_softc; + + mtx_assert(&sc->mtx, MA_OWNED); + usbd_transfer_start(sc->xfer[UEP_INTR_DT]); + + return (0); +} + +#else /* !EVDEV_SUPPORT */ + static void uep_start_read(struct usb_fifo *fifo) { @@ -422,6 +523,7 @@ usb_fifo_free_buffer(fifo); } } +#endif /* !EVDEV_SUPPORT */ static devclass_t uep_devclass; @@ -440,5 +542,8 @@ DRIVER_MODULE(uep, uhub, uep_driver, uep_devclass, NULL, NULL); MODULE_DEPEND(uep, usb, 1, 1, 1); +#ifdef EVDEV_SUPPORT +MODULE_DEPEND(uep, evdev, 1, 1, 1); +#endif MODULE_VERSION(uep, 1); USB_PNP_HOST_INFO(uep_devs); Index: sys/modules/usb/uep/Makefile =================================================================== --- sys/modules/usb/uep/Makefile +++ sys/modules/usb/uep/Makefile @@ -5,7 +5,7 @@ .PATH: $S/dev/usb/input KMOD= uep -SRCS= opt_bus.h opt_usb.h device_if.h bus_if.h usb_if.h vnode_if.h usbdevs.h \ - uep.c +SRCS= opt_bus.h opt_evdev.h opt_usb.h device_if.h bus_if.h usb_if.h \ + vnode_if.h usbdevs.h uep.c .include