svn commit: r358537 - head/sys/dev/acpica
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Mar 2 09:45:08 UTC 2020
Author: hselasky
Date: Mon Mar 2 09:45:06 2020
New Revision: 358537
URL: https://svnweb.freebsd.org/changeset/base/358537
Log:
Expose the ACPI power button, sleep button and LID state as evdev's.
This allows libinput to disable touchpads when the lid is closed and
various desktop environments can show power-off dialogs when the power
button is pressed. While the latter is doable with devd a
cross-platform solution is nicer.
Submitted by: Greg V <greg at unrelenting.technology>
Differential Revision: https://reviews.freebsd.org/D23863
MFC after: 1 week
Sponsored by: Mellanox Technologies
Modified:
head/sys/dev/acpica/acpi_button.c
head/sys/dev/acpica/acpi_lid.c
Modified: head/sys/dev/acpica/acpi_button.c
==============================================================================
--- head/sys/dev/acpica/acpi_button.c Mon Mar 2 09:16:48 2020 (r358536)
+++ head/sys/dev/acpica/acpi_button.c Mon Mar 2 09:45:06 2020 (r358537)
@@ -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 notif
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
Modified: head/sys/dev/acpica/acpi_lid.c
==============================================================================
--- head/sys/dev/acpica/acpi_lid.c Mon Mar 2 09:16:48 2020 (r358536)
+++ head/sys/dev/acpica/acpi_lid.c Mon Mar 2 09:45:06 2020 (r358537)
@@ -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
@@ -131,6 +146,20 @@ acpi_lid_attach(device_t dev)
sc = device_get_softc(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
More information about the svn-src-head
mailing list