Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/fdt For known Linux keycodes, report key press event...



details:   https://anonhg.NetBSD.org/src/rev/f5f01ae359a2
branches:  trunk
changeset: 356413:f5f01ae359a2
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sat Sep 23 23:54:30 2017 +0000

description:
For known Linux keycodes, report key press events through a wskbd device
instead of using sysmon pswitch hotkey events.

diffstat:

 sys/dev/fdt/files.fdt  |   4 +-
 sys/dev/fdt/gpiokeys.c |  94 +++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 88 insertions(+), 10 deletions(-)

diffs (208 lines):

diff -r 813038b71df4 -r f5f01ae359a2 sys/dev/fdt/files.fdt
--- a/sys/dev/fdt/files.fdt     Sat Sep 23 23:21:35 2017 +0000
+++ b/sys/dev/fdt/files.fdt     Sat Sep 23 23:54:30 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.fdt,v 1.20 2017/08/13 18:27:31 jmcneill Exp $
+# $NetBSD: files.fdt,v 1.21 2017/09/23 23:54:30 jmcneill Exp $
 
 include        "external/bsd/libfdt/conf/files.libfdt"
 
@@ -26,7 +26,7 @@
 attach ffclock at fdt
 file   dev/fdt/fixedfactorclock.c              ffclock
 
-device gpiokeys: sysmon_envsys, sysmon_power
+device gpiokeys: sysmon_envsys, sysmon_power, wskbddev, linux_keymap
 attach gpiokeys at fdt
 file   dev/fdt/gpiokeys.c                      gpiokeys
 
diff -r 813038b71df4 -r f5f01ae359a2 sys/dev/fdt/gpiokeys.c
--- a/sys/dev/fdt/gpiokeys.c    Sat Sep 23 23:21:35 2017 +0000
+++ b/sys/dev/fdt/gpiokeys.c    Sat Sep 23 23:54:30 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gpiokeys.c,v 1.4 2017/07/06 14:26:00 jmcneill Exp $ */
+/* $NetBSD: gpiokeys.c,v 1.5 2017/09/23 23:54:30 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gpiokeys.c,v 1.4 2017/07/06 14:26:00 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gpiokeys.c,v 1.5 2017/09/23 23:54:30 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -40,6 +40,12 @@
 #include <dev/sysmon/sysmonvar.h>
 #include <dev/sysmon/sysmon_taskq.h>
 
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wskbdvar.h>
+#include <dev/wscons/wsksymdef.h>
+#include <dev/wscons/wsksymvar.h>
+#include <dev/wscons/linux_keymap.h>
+
 #include <dev/fdt/fdtvar.h>
 
 #define GPIOKEYS_POLL_INTERVAL mstohz(200)
@@ -53,15 +59,23 @@
 static void    gpiokeys_tick(void *);
 static void    gpiokeys_task(void *);
 
+extern const struct wscons_keydesc ukbd_keydesctab[];
+static const struct wskbd_mapdata gpiokeys_keymapdata = {
+       ukbd_keydesctab,
+       KB_US,
+};
+
 struct gpiokeys_softc;
 
 struct gpiokeys_key {
+       struct gpiokeys_softc   *key_sc;
        int                     key_phandle;
        char                    *key_label;
        struct fdtbus_gpio_pin  *key_pin;
        u_int                   key_debounce;
        u_int                   key_code;
        struct sysmon_pswitch   key_pswitch;
+       uint8_t                 key_usbcode;
        u_int                   key_state;
 
        struct gpiokeys_key     *key_next;
@@ -77,12 +91,48 @@
 
        struct gpiokeys_key *sc_keys;
        callout_t       sc_tick;
+
+       device_t        sc_wskbddev;
+       int             sc_enabled;
 };
 
 CFATTACH_DECL_NEW(gpiokeys, sizeof(struct gpiokeys_softc),
     gpiokeys_match, gpiokeys_attach, NULL, NULL);
 
 static int
+gpiokeys_enable(void *v, int on)
+{
+       struct gpiokeys_softc * const sc = v;
+
+       sc->sc_enabled = on;
+
+       return 0;
+}
+
+static void
+gpiokeys_set_leds(void *v, int leds)
+{
+}
+
+static int
+gpiokeys_ioctl(void *v, u_long cmd, void *data, int flag, lwp_t *l)
+{
+       switch (cmd) {
+       case WSKBDIO_GTYPE:
+               *(int *)data = WSKBD_TYPE_USB;
+               return 0;
+       }
+
+       return EPASSTHROUGH;
+}
+
+static const struct wskbd_accessops gpiokeys_accessops = {
+       .enable = gpiokeys_enable,
+       .set_leds = gpiokeys_set_leds,
+       .ioctl = gpiokeys_ioctl
+};
+
+static int
 gpiokeys_match(device_t parent, cfdata_t cf, void *aux)
 {
        const char * const compatible[] = { "gpio-keys", NULL };
@@ -98,8 +148,9 @@
        const struct fdt_attach_args *faa = aux;
        const int phandle = faa->faa_phandle;
        struct gpiokeys_key *key;
+       u_int debounce, code;
+       int use_wskbddev = 0;
        int child, len;
-       u_int debounce, code;
 
        sc->sc_dev = self;
        sc->sc_phandle = phandle;
@@ -117,6 +168,7 @@
                        continue;
                }
                key = kmem_zalloc(sizeof(*key), KM_SLEEP);
+               key->key_sc = sc;
                key->key_phandle = child;
                key->key_code = code;
                key->key_label = kmem_zalloc(len, KM_SLEEP);
@@ -131,20 +183,28 @@
                if (key->key_pin)
                        key->key_state = fdtbus_gpio_read(key->key_pin);
 
-               key->key_pswitch.smpsw_name = key->key_label;
                switch (code) {
                case KEY_POWER:
+                       key->key_pswitch.smpsw_name = key->key_label;
                        key->key_pswitch.smpsw_type = PSWITCH_TYPE_POWER;
                        break;
                case KEY_SLEEP:
+                       key->key_pswitch.smpsw_name = key->key_label;
                        key->key_pswitch.smpsw_type = PSWITCH_TYPE_SLEEP;
                        break;
                default:
-                       key->key_pswitch.smpsw_type = PSWITCH_TYPE_HOTKEY;
+                       key->key_usbcode = linux_key_to_usb(code);
+                       if (key->key_usbcode != 0) {
+                               use_wskbddev++;
+                       } else {
+                               key->key_pswitch.smpsw_name = key->key_label;
+                               key->key_pswitch.smpsw_type = PSWITCH_TYPE_HOTKEY;
+                       }
                        break;
                }
 
-               if (sysmon_pswitch_register(&key->key_pswitch) != 0) {
+               if (key->key_pswitch.smpsw_name != NULL &&
+                   sysmon_pswitch_register(&key->key_pswitch) != 0) {
                        aprint_error(" %s:ERROR", key->key_label);
                        kmem_free(key->key_label, len);
                        kmem_free(key, sizeof(*key));
@@ -168,6 +228,17 @@
 
        aprint_normal("\n");
 
+       if (use_wskbddev > 0) {
+               struct wskbddev_attach_args a;
+               memset(&a, 0, sizeof(a));
+               a.console = false;
+               a.keymap = &gpiokeys_keymapdata;
+               a.accessops = &gpiokeys_accessops;
+               a.accesscookie = sc;
+               sc->sc_wskbddev = config_found_ia(self, "wskbddev", &a,
+                   wskbddevprint);
+       }
+
        callout_init(&sc->sc_tick, CALLOUT_MPSAFE);
        callout_setfunc(&sc->sc_tick, gpiokeys_tick, sc);
 
@@ -197,7 +268,14 @@
 gpiokeys_task(void *priv)
 {
        struct gpiokeys_key *key = priv;
+       struct gpiokeys_softc *sc = key->key_sc;
 
-       sysmon_pswitch_event(&key->key_pswitch,
-           key->key_state ? PSWITCH_EVENT_PRESSED : PSWITCH_EVENT_RELEASED);
+       if (key->key_pswitch.smpsw_name) {
+               sysmon_pswitch_event(&key->key_pswitch,
+                   key->key_state ? PSWITCH_EVENT_PRESSED : PSWITCH_EVENT_RELEASED);
+       } else if (sc->sc_enabled && sc->sc_wskbddev != NULL && key->key_usbcode != 0) {
+               wskbd_input(sc->sc_wskbddev,
+                   key->key_state ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP,
+                   key->key_usbcode);
+       }
 }



Home | Main Index | Thread Index | Old Index