]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
HID: Intel-thc-hid: Intel-thc: Add Wake-on-Touch support
authorEven Xu <even.xu@intel.com>
Wed, 14 May 2025 06:37:33 +0000 (14:37 +0800)
committerJiri Kosina <jkosina@suse.com>
Tue, 10 Jun 2025 19:19:50 +0000 (21:19 +0200)
Wake-on-Touch (WoT) feature gives system the capability to wake from
sleep state by user touch event, it requires platform providing wake
GPIO through ACPI resource.

Intel UEFI provides a user setting to enable or disable THC device WoT
feature. If it's enabled, UEFI assigns an additional wake GPIO resource
to THC device ACPI configuration, facilitating system wakeup.

This patch provides helper APIs for THC device driver to query wake
GPIO resource, enable WoT feature and unconfigure WoT.

APIs added:
- thc_wot_config(): Query and configure wake-on-touch feature.
- thc_wot_unconfig(): Unconfig wake-on-touch feature.

Signed-off-by: Even Xu <even.xu@intel.com>
Tested-by: Chong Han <chong.han@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
drivers/hid/intel-thc-hid/Makefile
drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.h
drivers/hid/intel-thc-hid/intel-thc/intel-thc-wot.c [new file with mode: 0644]
drivers/hid/intel-thc-hid/intel-thc/intel-thc-wot.h [new file with mode: 0644]

index 6f762d87af07089cd167fd9d7e43744b43f81f0c..f1182253b5b7013838c84c250e57ea4bef8c87c3 100644 (file)
@@ -8,6 +8,7 @@
 obj-$(CONFIG_INTEL_THC_HID) += intel-thc.o
 intel-thc-objs += intel-thc/intel-thc-dev.o
 intel-thc-objs += intel-thc/intel-thc-dma.o
+intel-thc-objs += intel-thc/intel-thc-wot.o
 
 obj-$(CONFIG_INTEL_QUICKSPI) += intel-quickspi.o
 intel-quickspi-objs += intel-quickspi/pci-quickspi.o
index 8666e2362e3243e3f7bc033ce328166c62d12e65..0db435335e249668483741764b8896f99d2f8d5e 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/workqueue.h>
 
 #include "intel-thc-dma.h"
+#include "intel-thc-wot.h"
 
 #define THC_REGMAP_COMMON_OFFSET  0x10
 #define THC_REGMAP_MMIO_OFFSET    0x1000
@@ -56,6 +57,7 @@ enum thc_int_type {
  * @port_type: Port type of THC port instance
  * @pio_int_supported: PIO interrupt supported flag
  * @dma_ctx: DMA specific data
+ * @wot: THC Wake-on-Touch data
  * @write_complete_wait: Signal event for DMA write complete
  * @swdma_complete_wait: Signal event for SWDMA sequence complete
  * @write_done: Bool value that indicates if DMA write is done
@@ -77,6 +79,8 @@ struct thc_device {
 
        struct thc_dma_context *dma_ctx;
 
+       struct thc_wot wot;
+
        wait_queue_head_t write_complete_wait;
        wait_queue_head_t swdma_complete_wait;
        bool write_done;
diff --git a/drivers/hid/intel-thc-hid/intel-thc/intel-thc-wot.c b/drivers/hid/intel-thc-hid/intel-thc/intel-thc-wot.c
new file mode 100644 (file)
index 0000000..1291b4e
--- /dev/null
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2025 Intel Corporation */
+
+#include <linux/acpi.h>
+#include <linux/pm_wakeirq.h>
+
+#include "intel-thc-dev.h"
+#include "intel-thc-wot.h"
+
+/**
+ * thc_wot_config - Query and configure wake-on-touch feature
+ * @thc_dev: Point to thc_device structure
+ * @gpio_map: Point to ACPI GPIO resource mapping structure
+ *
+ * THC ACPI device only provides _CRS with GpioInt() resources, doesn't contain
+ * _DSD to map this GPIO resource, so this function first registers wake GPIO
+ * mapping manually, then queries wake-on-touch GPIO resource from ACPI,
+ * if it exists and is wake-able, configure driver to enable it, otherwise,
+ * return immediately.
+ * This function will not return error as it doesn't impact major function.
+ */
+void thc_wot_config(struct thc_device *thc_dev, const struct acpi_gpio_mapping *gpio_map)
+{
+       struct acpi_device *adev;
+       struct thc_wot *wot;
+       int ret;
+
+       if (!thc_dev)
+               return;
+
+       adev = ACPI_COMPANION(thc_dev->dev);
+       if (!adev)
+               return;
+
+       wot = &thc_dev->wot;
+
+       ret = acpi_dev_add_driver_gpios(adev, gpio_map);
+       if (ret) {
+               dev_warn(thc_dev->dev, "Can't add wake GPIO resource, ret = %d\n", ret);
+               return;
+       }
+
+       wot->gpio_irq = acpi_dev_gpio_irq_wake_get_by(adev, "wake-on-touch", 0,
+                                                     &wot->gpio_irq_wakeable);
+       if (wot->gpio_irq <= 0) {
+               dev_warn(thc_dev->dev, "Can't find wake GPIO resource\n");
+               return;
+       }
+
+       if (!wot->gpio_irq_wakeable) {
+               dev_warn(thc_dev->dev, "GPIO resource isn't wakeable\n");
+               return;
+       }
+
+       ret = device_init_wakeup(thc_dev->dev, true);
+       if (ret) {
+               dev_warn(thc_dev->dev, "Failed to init wake up.\n");
+               return;
+       }
+
+       ret = dev_pm_set_dedicated_wake_irq(thc_dev->dev, wot->gpio_irq);
+       if (ret) {
+               dev_warn(thc_dev->dev, "Failed to set wake up IRQ.\n");
+               device_init_wakeup(thc_dev->dev, false);
+       }
+}
+EXPORT_SYMBOL_NS_GPL(thc_wot_config, "INTEL_THC");
+
+/**
+ * thc_wot_unconfig - Unconfig wake-on-touch feature
+ * @thc_dev: Point to thc_device structure
+ *
+ * Configure driver to disable wake-on-touch and release ACPI resource.
+ */
+void thc_wot_unconfig(struct thc_device *thc_dev)
+{
+       struct acpi_device *adev;
+
+       if (!thc_dev)
+               return;
+
+       adev = ACPI_COMPANION(thc_dev->dev);
+       if (!adev)
+               return;
+
+       if (thc_dev->wot.gpio_irq_wakeable)
+               device_init_wakeup(thc_dev->dev, false);
+
+       if (thc_dev->wot.gpio_irq > 0) {
+               dev_pm_clear_wake_irq(thc_dev->dev);
+               acpi_dev_remove_driver_gpios(adev);
+       }
+}
+EXPORT_SYMBOL_NS_GPL(thc_wot_unconfig, "INTEL_THC");
diff --git a/drivers/hid/intel-thc-hid/intel-thc/intel-thc-wot.h b/drivers/hid/intel-thc-hid/intel-thc/intel-thc-wot.h
new file mode 100644 (file)
index 0000000..6c70062
--- /dev/null
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2025 Intel Corporation */
+
+#ifndef _INTEL_THC_WOT_H_
+#define _INTEL_THC_WOT_H_
+
+#include <linux/types.h>
+
+#include <linux/gpio/consumer.h>
+
+/**
+ * struct thc_wot - THC Wake-on-Touch data structure
+ * @gpio_irq : GPIO interrupt IRQ number for wake-on-touch
+ * @gpio_irq_wakeable : Indicate GPIO IRQ workable or not
+ */
+struct thc_wot {
+       int gpio_irq;
+       bool gpio_irq_wakeable;
+};
+
+struct thc_device;
+
+void thc_wot_config(struct thc_device *thc_dev, const struct acpi_gpio_mapping *gpio_map);
+void thc_wot_unconfig(struct thc_device *thc_dev);
+
+#endif /* _INTEL_THC_WOT_H_ */