Date: Mon, 28 Jul 2014 22:10:16 +0000 (UTC) From: Jakub Wojciech Klama <jceel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r269199 - user/jceel/soc2014_evdev/head/sys/dev/usb/input Message-ID: <201407282210.s6SMAGPo034709@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jceel Date: Mon Jul 28 22:10:16 2014 New Revision: 269199 URL: http://svnweb.freebsd.org/changeset/base/269199 Log: Initial evdev support for uep(4). Modified: user/jceel/soc2014_evdev/head/sys/dev/usb/input/uep.c Modified: user/jceel/soc2014_evdev/head/sys/dev/usb/input/uep.c ============================================================================== --- user/jceel/soc2014_evdev/head/sys/dev/usb/input/uep.c Mon Jul 28 21:57:09 2014 (r269198) +++ user/jceel/soc2014_evdev/head/sys/dev/usb/input/uep.c Mon Jul 28 22:10:16 2014 (r269199) @@ -30,6 +30,8 @@ * http://home.eeti.com.tw/web20/drivers/Software%20Programming%20Guide_v2.0.pdf */ +#include "opt_evdev.h" + #include <sys/param.h> #include <sys/bus.h> #include <sys/callout.h> @@ -51,6 +53,11 @@ #include <sys/fcntl.h> #include <sys/tty.h> +#ifdef EVDEV +#include <dev/evdev/input.h> +#include <dev/evdev/evdev.h> +#endif + #define USB_DEBUG_VAR uep_debug #include <dev/usb/usb_debug.h> @@ -93,6 +100,11 @@ struct uep_softc { u_int pollrate; u_int state; #define UEP_ENABLED 0x01 +#define UEP_EV_OPENED 0x02 + +#ifdef EVDEV + struct evdev_dev *evdev; +#endif /* Reassembling buffer. */ u_char buf[UEP_PACKET_LEN_MAX]; @@ -110,6 +122,9 @@ static usb_fifo_cmd_t uep_stop_read; static usb_fifo_open_t uep_open; static usb_fifo_close_t uep_close; +static evdev_open_t uep_ev_open; +static evdev_close_t uep_ev_close; + static void uep_put_queue(struct uep_softc *, u_char *); static struct usb_fifo_methods uep_fifo_methods = { @@ -120,6 +135,11 @@ static struct usb_fifo_methods uep_fifo_ .basename[0] = "uep", }; +static struct evdev_methods uep_evdev_methods = { + .ev_open = &uep_ev_open, + .ev_close = &uep_ev_close, +}; + static int get_pkt_len(u_char *buf) { @@ -152,6 +172,7 @@ static void uep_process_pkt(struct uep_softc *sc, u_char *buf) { int32_t x, y; + int touch; if ((buf[0] & 0xFE) != 0x80) { DPRINTF("bad input packet format 0x%.2x\n", buf[0]); @@ -179,11 +200,19 @@ uep_process_pkt(struct uep_softc *sc, u_ * */ + touch = buf[0] & (1 << 0); x = (buf[1] << 7) | buf[2]; y = (buf[3] << 7) | buf[4]; DPRINTFN(2, "x %u y %u\n", x, y); +#ifdef EVDEV + evdev_push_event(sc->evdev, EV_ABS, ABS_X, x); + evdev_push_event(sc->evdev, EV_ABS, ABS_Y, y); + evdev_push_event(sc->evdev, EV_KEY, BTN_TOUCH, !!touch); + evdev_sync(sc->evdev); +#endif + uep_put_queue(sc, buf); } @@ -260,11 +289,17 @@ uep_intr_callback(struct usb_xfer *xfer, case USB_ST_SETUP: tr_setup: /* 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) { +#ifdef EVDEV + if ((sc->state & UEP_EV_OPENED) == 0) + break; +#else + break; +#endif + } + + usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); + usbd_transfer_submit(xfer); break; default: @@ -315,6 +350,9 @@ uep_attach(device_t dev) struct usb_attach_arg *uaa = device_get_ivars(dev); struct uep_softc *sc = device_get_softc(dev); int error; +#ifdef EVDEV + struct input_absinfo absinfo = { 0 }; +#endif device_set_usb_desc(dev); @@ -337,6 +375,29 @@ uep_attach(device_t dev) goto detach; } +#ifdef EVDEV + sc->evdev = evdev_alloc(); + evdev_set_name(sc->evdev, device_get_desc(dev)); + evdev_set_serial(sc->evdev, "0"); + evdev_set_softc(sc->evdev, sc); + evdev_set_methods(sc->evdev, &uep_evdev_methods); + evdev_support_event(sc->evdev, EV_SYN); + evdev_support_event(sc->evdev, EV_ABS); + evdev_support_event(sc->evdev, EV_KEY); + evdev_support_abs(sc->evdev, ABS_X); + evdev_support_abs(sc->evdev, ABS_Y); + + absinfo.minimum = 0; + absinfo.maximum = UEP_MAX_X; + evdev_set_absinfo(sc->evdev, ABS_X, &absinfo); + + absinfo.minimum = 0; + absinfo.maximum = UEP_MAX_Y; + evdev_set_absinfo(sc->evdev, ABS_Y, &absinfo); + + evdev_register(dev, sc->evdev); +#endif + sc->buf_len = 0; return (0); @@ -423,6 +484,36 @@ uep_close(struct usb_fifo *fifo, int ffl } } +static void +uep_ev_close(struct evdev_dev *evdev, void *ev_softc) +{ + struct uep_softc *sc = (struct uep_softc *)ev_softc; + + mtx_lock(&sc->mtx); + usbd_transfer_stop(sc->xfer[UEP_INTR_DT]); + mtx_unlock(&sc->mtx); + + sc->state &= ~(UEP_EV_OPENED); +} + +static int +uep_ev_open(struct evdev_dev *evdev, void *ev_softc) +{ + struct uep_softc *sc = (struct uep_softc *)ev_softc; + + mtx_lock(&sc->mtx); + + usbd_transfer_stop(sc->xfer[UEP_INTR_DT]); + usbd_xfer_set_interval(sc->xfer[UEP_INTR_DT], 100); + usbd_transfer_start(sc->xfer[UEP_INTR_DT]); + + mtx_unlock(&sc->mtx); + + sc->state |= UEP_EV_OPENED; + + return (0); +} + static devclass_t uep_devclass; static device_method_t uep_methods[] = {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407282210.s6SMAGPo034709>