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@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
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to