1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2025 Intel Corporation */ 3 4 #include <linux/acpi.h> 5 #include <linux/pm_wakeirq.h> 6 7 #include "intel-thc-dev.h" 8 #include "intel-thc-wot.h" 9 10 /** 11 * thc_wot_config - Query and configure wake-on-touch feature 12 * @thc_dev: Point to thc_device structure 13 * @gpio_map: Point to ACPI GPIO resource mapping structure 14 * 15 * THC ACPI device only provides _CRS with GpioInt() resources, doesn't contain 16 * _DSD to map this GPIO resource, so this function first registers wake GPIO 17 * mapping manually, then queries wake-on-touch GPIO resource from ACPI, 18 * if it exists and is wake-able, configure driver to enable it, otherwise, 19 * return immediately. 20 * This function will not return error as it doesn't impact major function. 21 */ 22 void thc_wot_config(struct thc_device *thc_dev, const struct acpi_gpio_mapping *gpio_map) 23 { 24 struct acpi_device *adev; 25 struct thc_wot *wot; 26 int ret; 27 28 if (!thc_dev) 29 return; 30 31 adev = ACPI_COMPANION(thc_dev->dev); 32 if (!adev) 33 return; 34 35 wot = &thc_dev->wot; 36 37 ret = acpi_dev_add_driver_gpios(adev, gpio_map); 38 if (ret) { 39 dev_warn(thc_dev->dev, "Can't add wake GPIO resource, ret = %d\n", ret); 40 return; 41 } 42 43 wot->gpio_irq = acpi_dev_gpio_irq_wake_get_by(adev, "wake-on-touch", 0, 44 &wot->gpio_irq_wakeable); 45 if (wot->gpio_irq <= 0) { 46 dev_warn(thc_dev->dev, "Can't find wake GPIO resource\n"); 47 return; 48 } 49 50 if (!wot->gpio_irq_wakeable) { 51 dev_warn(thc_dev->dev, "GPIO resource isn't wakeable\n"); 52 return; 53 } 54 55 ret = device_init_wakeup(thc_dev->dev, true); 56 if (ret) { 57 dev_warn(thc_dev->dev, "Failed to init wake up.\n"); 58 return; 59 } 60 61 ret = dev_pm_set_dedicated_wake_irq(thc_dev->dev, wot->gpio_irq); 62 if (ret) { 63 dev_warn(thc_dev->dev, "Failed to set wake up IRQ.\n"); 64 device_init_wakeup(thc_dev->dev, false); 65 } 66 } 67 EXPORT_SYMBOL_NS_GPL(thc_wot_config, "INTEL_THC"); 68 69 /** 70 * thc_wot_unconfig - Unconfig wake-on-touch feature 71 * @thc_dev: Point to thc_device structure 72 * 73 * Configure driver to disable wake-on-touch and release ACPI resource. 74 */ 75 void thc_wot_unconfig(struct thc_device *thc_dev) 76 { 77 struct acpi_device *adev; 78 79 if (!thc_dev) 80 return; 81 82 adev = ACPI_COMPANION(thc_dev->dev); 83 if (!adev) 84 return; 85 86 if (thc_dev->wot.gpio_irq_wakeable) 87 device_init_wakeup(thc_dev->dev, false); 88 89 if (thc_dev->wot.gpio_irq > 0) { 90 dev_pm_clear_wake_irq(thc_dev->dev); 91 acpi_dev_remove_driver_gpios(adev); 92 } 93 } 94 EXPORT_SYMBOL_NS_GPL(thc_wot_unconfig, "INTEL_THC"); 95