Skip to content

Instantly share code, notes, and snippets.

@johalun
Created April 21, 2019 20:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johalun/3c67a678e740b82512cec52bfe926092 to your computer and use it in GitHub Desktop.
Save johalun/3c67a678e740b82512cec52bfe926092 to your computer and use it in GitHub Desktop.
Implement evdev for iichid
diff --git a/sys/dev/iicbus/input/iichid.c b/sys/dev/iicbus/input/iichid.c
index 68b8b1e4d9b6..fe0e3fd96f4f 100644
--- a/sys/dev/iicbus/input/iichid.c
+++ b/sys/dev/iicbus/input/iichid.c
@@ -34,6 +34,12 @@
#include <dev/iicbus/iiconf.h>
#include "iicbus_if.h"
+#include "opt_evdev.h"
+
+#ifdef EVDEV_SUPPORT
+#include <dev/evdev/input.h>
+#include <dev/evdev/evdev.h>
+#endif
static device_probe_t iichid_probe;
static device_attach_t iichid_attach;
@@ -71,6 +77,19 @@ static driver_t iichid_driver = {
.size = sizeof(struct iichid_softc),
};
+
+#ifdef EVDEV_SUPPORT
+static evdev_open_t iichid_ev_open;
+static evdev_close_t iichid_ev_close;
+static void iichid_evdev_push(struct iichid_softc *, int32_t, int32_t,
+ int32_t, int32_t, int32_t);
+
+static const struct evdev_methods iichid_evdev_methods = {
+ .ev_open = &iichid_ev_open,
+ .ev_close = &iichid_ev_close,
+};
+#endif
+
static int
iichid_fetch_buffer(device_t dev, uint8_t* cmd, int cmdlen, uint8_t *buf, int buflen)
{
@@ -295,6 +314,30 @@ iichid_close(struct cdev *dev, int fflags, int devtype, struct thread *td)
return 0;
}
+#ifdef EVDEV_SUPPORT
+static int
+iichid_ev_open(struct evdev_dev *evdev)
+{
+ struct iichid_softc *sc = evdev_get_softc(evdev);
+
+ mtx_assert(&sc->lock, MA_OWNED);
+ sc->sc_evflags = MS_EVDEV_OPENED;
+
+ return (0);
+}
+
+static int
+iichid_ev_close(struct evdev_dev *evdev)
+{
+ struct iichid_softc *sc = evdev_get_softc(evdev);
+
+ mtx_assert(&sc->lock, MA_OWNED);
+ sc->sc_evflags = 0;
+
+ return (0);
+}
+#endif
+
static int
iichid_write(struct cdev *dev, struct uio *uio, int ioflags)
{
@@ -495,6 +538,29 @@ ms_put_queue(struct iichid_softc *sc, int32_t dx, int32_t dy,
}
}
+#ifdef EVDEV_SUPPORT
+static void
+iichid_evdev_push(struct iichid_softc *sc, int32_t dx, int32_t dy,
+ int32_t dz, int32_t dt, int32_t buttons)
+{
+ if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) {
+ /* Push evdev event */
+ if (sc->invert != 0)
+ dz = -dz;
+ evdev_push_rel(sc->sc_evdev, REL_X, dx);
+ evdev_push_rel(sc->sc_evdev, REL_Y, -dy);
+ evdev_push_rel(sc->sc_evdev, REL_WHEEL, -dz);
+ evdev_push_rel(sc->sc_evdev, REL_HWHEEL, dt);
+ evdev_push_mouse_btn(sc->sc_evdev,
+ (buttons & ~MOUSE_STDBUTTONS) |
+ (buttons & (1 << 2) ? MOUSE_BUTTON1DOWN : 0) |
+ (buttons & (1 << 1) ? MOUSE_BUTTON2DOWN : 0) |
+ (buttons & (1 << 0) ? MOUSE_BUTTON3DOWN : 0));
+ evdev_sync(sc->sc_evdev);
+ }
+}
+#endif
+
static void
iichid_event(void* context, int pending)
{
@@ -526,6 +592,9 @@ iichid_event(void* context, int pending)
int32_t dt = 0;
int32_t buttons = 0;
int32_t buttons_found = 0;
+#ifdef EVDEV_SUPPORT
+ int32_t buttons_reported = 0;
+#endif
uint8_t id = 0;
uint8_t *buf = sc->input_buf;
@@ -582,6 +651,10 @@ iichid_event(void* context, int pending)
/* register button mask */
buttons_found |= mask;
}
+
+#ifdef EVDEV_SUPPORT
+ buttons_reported = buttons;
+#endif
buttons |= sc->sc_status.button & ~buttons_found;
@@ -605,6 +678,9 @@ iichid_event(void* context, int pending)
//device_printf(sc->dev, "dx: %d, dy: %d, dz: %d, dt: %d, dw: %d, btn: 0x%2x\n", dx, dy, dz, dt, dw, buttons);
ms_put_queue(sc, dx, dy, dz, dt, buttons);
+#ifdef EVDEV_SUPPORT
+ iichid_evdev_push(sc, dx, dy, dz, dt, buttons_reported);
+#endif
}
}
@@ -668,7 +744,9 @@ iichid_attach(device_t dev)
uintptr_t addr = 0, cr = 0;
int error;
-
+#ifdef EVDEV_SUPPORT
+ struct ms_info *info;
+#endif
sc->dev = dev;
sc->detaching = false;
sc->input_buf = NULL;
@@ -749,6 +827,43 @@ iichid_attach(device_t dev)
STAILQ_INSERT_TAIL(&sc->ms_unused_blocks, u, next);
}
+#ifdef EVDEV_SUPPORT
+ sc->sc_evdev = evdev_alloc();
+ evdev_set_name(sc->sc_evdev, device_get_desc(dev));
+ evdev_set_phys(sc->sc_evdev, device_get_nameunit(dev));
+ evdev_set_id(sc->sc_evdev, BUS_I2C, sc->desc.wVendorID,
+ sc->desc.wProductID, 0);
+ evdev_set_serial(sc->sc_evdev, "");
+ evdev_set_methods(sc->sc_evdev, sc, &iichid_evdev_methods);
+ evdev_support_prop(sc->sc_evdev, INPUT_PROP_POINTER);
+ evdev_support_event(sc->sc_evdev, EV_SYN);
+ evdev_support_event(sc->sc_evdev, EV_REL);
+ evdev_support_event(sc->sc_evdev, EV_KEY);
+
+ info = &sc->info[0];
+
+ if (info->sc_flags & MS_FLAG_X_AXIS)
+ evdev_support_rel(sc->sc_evdev, REL_X);
+
+ if (info->sc_flags & MS_FLAG_Y_AXIS)
+ evdev_support_rel(sc->sc_evdev, REL_Y);
+
+ if (info->sc_flags & MS_FLAG_Z_AXIS)
+ evdev_support_rel(sc->sc_evdev, REL_WHEEL);
+
+ if (info->sc_flags & MS_FLAG_T_AXIS)
+ evdev_support_rel(sc->sc_evdev, REL_HWHEEL);
+
+ for (int i = 0; i < info->sc_buttons; i++)
+ evdev_support_key(sc->sc_evdev, BTN_MOUSE + i);
+
+ error = evdev_register_mtx(sc->sc_evdev, &sc->lock);
+ if (error) {
+ iichid_detach(dev);
+ device_printf(dev, "could not register evdev mutex for device. error: %d\n", error);
+ }
+#endif
+
// device_printf(dev, "len: %d\nbcdVer: %d\nreport len: %d\ninput len: %d\nvid: 0x%x\npid: 0x%x\n", hid_desc.wHIDDescLength, hid_desc.bcdVersion, hid_desc.wReportDescLength, hid_desc.wMaxInputLength, hid_desc.wVendorID, hid_desc.wProductID);
return (0); /* success */
@@ -783,6 +898,10 @@ iichid_detach(device_t dev)
}
}
+#ifdef EVDEV_SUPPORT
+ evdev_free(sc->sc_evdev);
+#endif
+
if (sc->cdev)
destroy_dev(sc->cdev);
diff --git a/sys/dev/iicbus/input/iichid.h b/sys/dev/iicbus/input/iichid.h
index 4c09847403c9..3f05e4864f51 100644
--- a/sys/dev/iicbus/input/iichid.h
+++ b/sys/dev/iicbus/input/iichid.h
@@ -28,6 +28,8 @@
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
+#include "opt_evdev.h"
+
/* 5.1.1 - HID Descriptor Format */
struct i2c_hid_desc {
uint16_t wHIDDescLength;
@@ -122,6 +124,12 @@ struct iichid_softc {
uint8_t *input_buf;
int input_size;
+
+#ifdef EVDEV_SUPPORT
+ int sc_evflags;
+#define MS_EVDEV_OPENED 1
+ struct evdev_dev *sc_evdev;
+#endif
};
struct acpi_iichid_softc {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment