Index: sys/dev/gpio/gpiokeys.c =================================================================== --- sys/dev/gpio/gpiokeys.c +++ sys/dev/gpio/gpiokeys.c @@ -29,6 +29,7 @@ #include "opt_platform.h" #include "opt_kbd.h" +#include "opt_evdev.h" #include #include @@ -56,6 +57,11 @@ #include #include +#ifdef EVDEV_SUPPORT +#include +#include +#endif + #define KBD_DRIVER_NAME "gpiokeys" #define GPIOKEYS_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) @@ -99,6 +105,10 @@ struct resource *irq_res; void *intr_hl; struct mtx mtx; +#ifdef EVDEV_SUPPORT + struct evdev_dev *evdev; + uint32_t evcode; +#endif uint32_t keycode; int autorepeat; struct callout debounce_callout; @@ -171,23 +181,30 @@ } static void -gpiokeys_key_event(struct gpiokeys_softc *sc, uint16_t keycode, int pressed) +gpiokeys_key_event(struct gpiokeys_softc *sc, struct gpiokey *key, int pressed) { - uint32_t key; + uint32_t code; +#ifdef EVDEV_SUPPORT + if (key->evcode != GPIOKEY_NONE) { + evdev_push_key(key->evdev, key->evcode, pressed); + evdev_sync(key->evdev); /* XXX */ + } +#endif + if (key->keycode == GPIOKEY_NONE) + return; - key = keycode & SCAN_KEYCODE_MASK; - + code = key->keycode & SCAN_KEYCODE_MASK; if (!pressed) - key |= KEY_RELEASE; + code |= KEY_RELEASE; GPIOKEYS_LOCK(sc); - if (keycode & SCAN_PREFIX_E0) + if (key->keycode & SCAN_PREFIX_E0) gpiokeys_put_key(sc, 0xe0); - else if (keycode & SCAN_PREFIX_E1) + else if (key->keycode & SCAN_PREFIX_E1) gpiokeys_put_key(sc, 0xe1); - gpiokeys_put_key(sc, key); + gpiokeys_put_key(sc, code); GPIOKEYS_UNLOCK(sc); gpiokeys_event_keyinput(sc); @@ -200,11 +217,8 @@ key = arg; - if (key->keycode == GPIOKEY_NONE) - return; + gpiokeys_key_event(key->parent_sc, key, 1); - gpiokeys_key_event(key->parent_sc, key->keycode, 1); - callout_reset(&key->repeat_callout, key->repeat, gpiokey_autorepeat, key); } @@ -217,12 +231,9 @@ key = arg; - if (key->keycode == GPIOKEY_NONE) - return; - gpio_pin_is_active(key->pin, &active); if (active) { - gpiokeys_key_event(key->parent_sc, key->keycode, 1); + gpiokeys_key_event(key->parent_sc, key, 1); if (key->autorepeat) { callout_reset(&key->repeat_callout, key->repeat_delay, gpiokey_autorepeat, key); @@ -232,7 +243,7 @@ if (key->autorepeat && callout_pending(&key->repeat_callout)) callout_stop(&key->repeat_callout); - gpiokeys_key_event(key->parent_sc, key->keycode, 0); + gpiokeys_key_event(key->parent_sc, key, 0); } } @@ -254,7 +265,37 @@ GPIOKEY_UNLOCK(key); } +#ifdef EVDEV_SUPPORT static void +gpiokeys_evdev_register_key(struct gpiokey *key, const char *name, + uint32_t evcode) +{ + struct evdev_dev *evdev; + int error; + + evdev = evdev_alloc(); + evdev_set_name(evdev, name); + evdev_set_phys(evdev, + device_get_nameunit(key->parent_sc->sc_dev));/* XXX */ + evdev_set_id(evdev, BUS_VIRTUAL, 0, 0, 0); /* XXX */ + evdev_support_prop(evdev, INPUT_PROP_DIRECT); /* XXX */ + evdev_support_event(evdev, EV_SYN); + evdev_support_event(evdev, EV_KEY); + evdev_support_key(evdev, evcode); + + error = evdev_register_mtx(evdev, &key->mtx); + if (error == 0) { + key->evdev = evdev; + key->evcode = evcode; + } else { + evdev_free(evdev); + device_printf(key->parent_sc->sc_dev, "failed to register " + "evdev for key %s\n", name); + } +} +#endif + +static void gpiokeys_attach_key(struct gpiokeys_softc *sc, phandle_t node, struct gpiokey *key) { @@ -301,6 +342,9 @@ if (key->keycode == GPIOKEY_NONE) device_printf(sc->sc_dev, "<%s> failed to map linux,code value 0x%x\n", key_name, code); +#ifdef EVDEV_SUPPORT + gpiokeys_evdev_register_key(key, key_name, code); +#endif } else device_printf(sc->sc_dev, "<%s> no linux,code or freebsd,code property\n", @@ -365,7 +409,9 @@ if (key->pin) gpio_pin_release(key->pin); GPIOKEY_UNLOCK(key); - +#ifdef EVDEV_SUPPORT + evdev_unregister(key->evdev); +#endif GPIOKEY_LOCK_DESTROY(key); }