Created
April 21, 2019 20:34
-
-
Save johalun/3c67a678e740b82512cec52bfe926092 to your computer and use it in GitHub Desktop.
Implement evdev for iichid
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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