diff options
-rw-r--r-- | sys/dev/acpica/acpi_button.c | 34 | ||||
-rw-r--r-- | sys/dev/acpica/acpi_lid.c | 29 |
2 files changed, 63 insertions, 0 deletions
diff --git a/sys/dev/acpica/acpi_button.c b/sys/dev/acpica/acpi_button.c index 2e9e21e471ecf..dc0ea7225cba8 100644 --- a/sys/dev/acpica/acpi_button.c +++ b/sys/dev/acpica/acpi_button.c @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #include "opt_acpi.h" +#include "opt_evdev.h" #include <sys/param.h> #include <sys/kernel.h> #include <sys/module.h> @@ -40,6 +41,11 @@ __FBSDID("$FreeBSD$"); #include <dev/acpica/acpivar.h> +#ifdef EVDEV_SUPPORT +#include <dev/evdev/input.h> +#include <dev/evdev/evdev.h> +#endif + /* Hooks for the ACPI CA debugging infrastructure */ #define _COMPONENT ACPI_BUTTON ACPI_MODULE_NAME("BUTTON") @@ -51,6 +57,9 @@ struct acpi_button_softc { #define ACPI_POWER_BUTTON 0 #define ACPI_SLEEP_BUTTON 1 boolean_t fixed; +#ifdef EVDEV_SUPPORT + struct evdev_dev *button_evdev; +#endif }; #define ACPI_NOTIFY_BUTTON_PRESSED_FOR_SLEEP 0x80 @@ -142,6 +151,20 @@ acpi_button_attach(device_t dev) event = (sc->button_type == ACPI_SLEEP_BUTTON) ? ACPI_EVENT_SLEEP_BUTTON : ACPI_EVENT_POWER_BUTTON; +#ifdef EVDEV_SUPPORT + sc->button_evdev = evdev_alloc(); + evdev_set_name(sc->button_evdev, device_get_desc(dev)); + evdev_set_phys(sc->button_evdev, device_get_nameunit(dev)); + evdev_set_id(sc->button_evdev, BUS_HOST, 0, 0, 1); + evdev_support_event(sc->button_evdev, EV_SYN); + evdev_support_event(sc->button_evdev, EV_KEY); + evdev_support_key(sc->button_evdev, + (sc->button_type == ACPI_SLEEP_BUTTON) ? KEY_SLEEP : KEY_POWER); + + if (evdev_register(sc->button_evdev)) + return (ENXIO); +#endif + /* * Install the new handler. We could remove any fixed handlers added * from the FADT once we have a duplicate from the AML but some systems @@ -248,6 +271,9 @@ static void acpi_button_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) { struct acpi_button_softc *sc; +#ifdef EVDEV_SUPPORT + uint16_t key; +#endif ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, notify); @@ -263,6 +289,14 @@ acpi_button_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) device_printf(sc->button_dev, "unknown notify %#x\n", notify); break; } + +#ifdef EVDEV_SUPPORT + key = (sc->button_type == ACPI_SLEEP_BUTTON) ? KEY_SLEEP : KEY_POWER; + evdev_push_key(sc->button_evdev, key, 1); + evdev_sync(sc->button_evdev); + evdev_push_key(sc->button_evdev, key, 0); + evdev_sync(sc->button_evdev); +#endif } static ACPI_STATUS diff --git a/sys/dev/acpica/acpi_lid.c b/sys/dev/acpica/acpi_lid.c index aab64abb23382..25d9551b81fa1 100644 --- a/sys/dev/acpica/acpi_lid.c +++ b/sys/dev/acpica/acpi_lid.c @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include "opt_acpi.h" +#include "opt_evdev.h" #include <sys/param.h> #include <sys/eventhandler.h> #include <sys/kernel.h> @@ -43,6 +44,11 @@ __FBSDID("$FreeBSD$"); #include <dev/acpica/acpivar.h> +#ifdef EVDEV_SUPPORT +#include <dev/evdev/input.h> +#include <dev/evdev/evdev.h> +#endif + /* Hooks for the ACPI CA debugging infrastructure */ #define _COMPONENT ACPI_BUTTON ACPI_MODULE_NAME("LID") @@ -51,6 +57,9 @@ struct acpi_lid_softc { device_t lid_dev; ACPI_HANDLE lid_handle; int lid_status; /* open or closed */ +#ifdef EVDEV_SUPPORT + struct evdev_dev *lid_evdev; +#endif }; ACPI_HANDLE acpi_lid_handle; @@ -104,6 +113,12 @@ acpi_lid_status_update(struct acpi_lid_softc *sc) /* range check value */ sc->lid_status = lid_status ? 1 : 0; + +#ifdef EVDEV_SUPPORT + /* Notify evdev about lid status */ + evdev_push_sw(sc->lid_evdev, SW_LID, lid_status ? 0 : 1); + evdev_sync(sc->lid_evdev); +#endif } static int @@ -132,6 +147,20 @@ acpi_lid_attach(device_t dev) sc->lid_dev = dev; acpi_lid_handle = sc->lid_handle = acpi_get_handle(dev); +#ifdef EVDEV_SUPPORT + /* Register evdev device before initial status update */ + sc->lid_evdev = evdev_alloc(); + evdev_set_name(sc->lid_evdev, device_get_desc(dev)); + evdev_set_phys(sc->lid_evdev, device_get_nameunit(dev)); + evdev_set_id(sc->lid_evdev, BUS_HOST, 0, 0, 1); + evdev_support_event(sc->lid_evdev, EV_SYN); + evdev_support_event(sc->lid_evdev, EV_SW); + evdev_support_sw(sc->lid_evdev, SW_LID); + + if (evdev_register(sc->lid_evdev)) + return (ENXIO); +#endif + /* * If a system does not get lid events, it may make sense to change * the type to ACPI_ALL_NOTIFY. Some systems generate both a wake and |