forked from kofal.net/zmk
refactor: Fixes for soft-off based on review.
* Better naming for gpio-key behavior triggers. * Tweaks to scanned behavior trigger to avoid bad semaphore use, and reduce chance of issues with slowly scanned matrixes. * Various code cleanups of style issues.
This commit is contained in:
committed by
Pete Johanson
parent
96968514e3
commit
fceb0351a5
96
app/src/gpio_key_wakeup_trigger.c
Normal file
96
app/src/gpio_key_wakeup_trigger.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2023 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/init.h>
|
||||
#include <zephyr/pm/device.h>
|
||||
#include <zephyr/pm/pm.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#define DT_DRV_COMPAT zmk_gpio_key_wakeup_trigger
|
||||
|
||||
struct gpio_key_wakeup_trigger_config {
|
||||
struct gpio_dt_spec trigger;
|
||||
size_t extra_gpios_count;
|
||||
struct gpio_dt_spec extra_gpios[];
|
||||
};
|
||||
|
||||
static int zmk_gpio_key_wakeup_trigger_init(const struct device *dev) {
|
||||
#if IS_ENABLED(CONFIG_PM_DEVICE)
|
||||
pm_device_init_suspended(dev);
|
||||
pm_device_wakeup_enable(dev, true);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_PM_DEVICE)
|
||||
|
||||
static int gpio_key_wakeup_trigger_pm_resume(const struct device *dev) {
|
||||
const struct gpio_key_wakeup_trigger_config *config = dev->config;
|
||||
|
||||
int ret = gpio_pin_interrupt_configure_dt(&config->trigger, GPIO_INT_LEVEL_ACTIVE);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to configure wakeup trigger key GPIO pin interrupt (%d)", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (int i = 0; i < config->extra_gpios_count; i++) {
|
||||
ret = gpio_pin_configure_dt(&config->extra_gpios[i], GPIO_OUTPUT_ACTIVE);
|
||||
if (ret < 0) {
|
||||
LOG_WRN("Failed to set extra GPIO pin active for waker (%d)", ret);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gpio_key_wakeup_trigger_pm_suspend(const struct device *dev) {
|
||||
const struct gpio_key_wakeup_trigger_config *config = dev->config;
|
||||
|
||||
int ret = gpio_pin_interrupt_configure_dt(&config->trigger, GPIO_INT_DISABLE);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to configure wakeup trigger key GPIO pin interrupt (%d)", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gpio_key_wakeup_trigger_pm_action(const struct device *dev,
|
||||
enum pm_device_action action) {
|
||||
switch (action) {
|
||||
case PM_DEVICE_ACTION_RESUME:
|
||||
return gpio_key_wakeup_trigger_pm_resume(dev);
|
||||
case PM_DEVICE_ACTION_SUSPEND:
|
||||
return gpio_key_wakeup_trigger_pm_suspend(dev);
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_PM_DEVICE)
|
||||
|
||||
#define WAKEUP_TRIGGER_EXTRA_GPIO_SPEC(idx, n) \
|
||||
GPIO_DT_SPEC_GET_BY_IDX(DT_DRV_INST(n), extra_gpios, idx)
|
||||
|
||||
#define GPIO_KEY_WAKEUP_TRIGGER_INST(n) \
|
||||
const struct gpio_key_wakeup_trigger_config wtk_cfg_##n = { \
|
||||
.trigger = GPIO_DT_SPEC_GET(DT_INST_PROP(n, trigger), gpios), \
|
||||
.extra_gpios = {LISTIFY(DT_PROP_LEN_OR(DT_DRV_INST(n), extra_gpios, 0), \
|
||||
WAKEUP_TRIGGER_EXTRA_GPIO_SPEC, (, ), n)}, \
|
||||
.extra_gpios_count = DT_PROP_LEN_OR(DT_DRV_INST(n), extra_gpios, 0), \
|
||||
}; \
|
||||
PM_DEVICE_DT_INST_DEFINE(n, gpio_key_wakeup_trigger_pm_action); \
|
||||
DEVICE_DT_INST_DEFINE(n, zmk_gpio_key_wakeup_trigger_init, PM_DEVICE_DT_INST_GET(n), NULL, \
|
||||
&wtk_cfg_##n, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(GPIO_KEY_WAKEUP_TRIGGER_INST)
|
||||
Reference in New Issue
Block a user