uep(4): add evdev support

To compile this driver with evdev support enabled, place
following lines into the kernel configuration file:

options EVDEV_SUPPORT
device evdev

Note: Native and evdev modes are mutually exclusive.

Reviewed by:	gonzo, wblock (docs)
MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D11156
This commit is contained in:
Vladimir Kondratyev 2018-08-05 11:14:13 +00:00
parent 69acf61478
commit 26f3e847c3
3 changed files with 131 additions and 18 deletions

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd May 25, 2010
.Dd August 5, 2018
.Dt UEP 4
.Os
.Sh NAME
@ -44,28 +44,46 @@ module at boot time, place the following line in
.Bd -literal -offset indent
uep_load="YES"
.Ed
.Pp
To compile this driver with evdev support enabled, place the
following lines into the kernel configuration file:
.Bd -ragged -offset indent
.Cd "options EVDEV_SUPPORT"
.Cd "device evdev"
.Ed
.Sh DESCRIPTION
The
.Nm
driver provides support for the eGalax onscreen touch panels.
.Pp
The driver is stub.
It just probes and attaches to USB device, creates device entry
The driver is a stub.
It just probes and attaches to USB device, creates a device entry
and feeds reassembled packets from the hardware to it.
Depending on compile-time kernel options it supports either native
or evdev operation modes.
.Pp
To get mouse working in
.Xr X 7 ,
one needs to install
To get the mouse working in
.Xr X 7
in native mode, install
.Pa ports/x11-drivers/xf86-input-egalax .
.Pp
To get the mouse working in
.Xr X 7
in evdev mode, install
.Pa ports/x11-drivers/xf86-input-evdev .
.Sh FILES
.Nm
creates a blocking pseudo\-device file,
.Pa /dev/uep0 .
creates a blocking pseudo-device file,
.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
@ -74,6 +92,8 @@ driver was written by
.An Gleb Smirnoff Aq Mt glebius@FreeBSD.org .
.Sh BUGS
.Nm
can't act like
cannot act like
.Xr sysmouse 4 ,
since the latter does not support absolute motion events.
as
.Xr sysmouse 4
does not support absolute motion events.

View File

@ -32,6 +32,8 @@
* http://www.eeti.com.tw/pdf/Software%20Programming%20Guide_v2.0.pdf
*/
#include "opt_evdev.h"
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/callout.h>
@ -49,9 +51,14 @@
#include <dev/usb/usbhid.h>
#include "usbdevs.h"
#ifdef EVDEV_SUPPORT
#include <dev/evdev/input.h>
#include <dev/evdev/evdev.h>
#else
#include <sys/ioccom.h>
#include <sys/fcntl.h>
#include <sys/tty.h>
#endif
#define USB_DEBUG_VAR uep_debug
#include <dev/usb/usb_debug.h>
@ -90,11 +97,15 @@ struct uep_softc {
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];
@ -107,6 +118,18 @@ static device_probe_t uep_probe;
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;
@ -121,6 +144,7 @@ static struct usb_fifo_methods uep_fifo_methods = {
.f_stop_read = &uep_stop_read,
.basename[0] = "uep",
};
#endif /* !EVDEV_SUPPORT */
static int
get_pkt_len(u_char *buf)
@ -154,6 +178,9 @@ static void
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) {
DPRINTF("bad input packet format 0x%.2x\n", buf[0]);
@ -186,7 +213,17 @@ uep_process_pkt(struct uep_softc *sc, u_char *buf)
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);
}
evdev_push_key(sc->evdev, BTN_TOUCH, touch);
evdev_sync(sc->evdev);
#else
uep_put_queue(sc, buf);
#endif
}
static void
@ -261,12 +298,13 @@ uep_intr_callback(struct usb_xfer *xfer, usb_error_t error)
}
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:
@ -330,6 +368,28 @@ uep_attach(device_t dev)
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, 0);
evdev_support_abs(sc->evdev, ABS_Y, 0, 0, UEP_MAX_Y, 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);
@ -338,6 +398,7 @@ uep_attach(device_t dev)
DPRINTF("usb_fifo_attach error=%s\n", usbd_errstr(error));
goto detach;
}
#endif /* !EVDEV_SUPPORT */
sc->buf_len = 0;
@ -354,7 +415,11 @@ uep_detach(device_t dev)
{
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);
@ -363,6 +428,30 @@ uep_detach(device_t dev)
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)
{
@ -424,6 +513,7 @@ uep_close(struct usb_fifo *fifo, int fflags)
usb_fifo_free_buffer(fifo);
}
}
#endif /* !EVDEV_SUPPORT */
static devclass_t uep_devclass;
@ -442,5 +532,8 @@ static driver_t uep_driver = {
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);

View File

@ -5,7 +5,7 @@ S= ${SRCTOP}/sys
.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 <bsd.kmod.mk>