fix: Adjustments for Zephyr 3.5.
This commit is contained in:
parent
bd21f41412
commit
8d54e287f0
5 changed files with 79 additions and 61 deletions
|
@ -405,6 +405,7 @@ config ZMK_SLEEP
|
||||||
bool "Enable deep sleep support"
|
bool "Enable deep sleep support"
|
||||||
depends on HAS_POWEROFF
|
depends on HAS_POWEROFF
|
||||||
select POWEROFF
|
select POWEROFF
|
||||||
|
select ZMK_PM_DEVICE_SUSPEND_RESUME
|
||||||
imply USB
|
imply USB
|
||||||
|
|
||||||
if ZMK_SLEEP
|
if ZMK_SLEEP
|
||||||
|
@ -426,10 +427,15 @@ config ZMK_EXT_POWER
|
||||||
config ZMK_PM
|
config ZMK_PM
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config ZMK_PM_DEVICE_SUSPEND_RESUME
|
||||||
|
bool
|
||||||
|
select ZMK_PM
|
||||||
|
|
||||||
config ZMK_PM_SOFT_OFF
|
config ZMK_PM_SOFT_OFF
|
||||||
bool "Soft-off support"
|
bool "Soft-off support"
|
||||||
select ZMK_PM
|
select ZMK_PM
|
||||||
select PM_DEVICE
|
select PM_DEVICE
|
||||||
|
select ZMK_PM_DEVICE_SUSPEND_RESUME
|
||||||
|
|
||||||
config ZMK_GPIO_KEY_WAKEUP_TRIGGER
|
config ZMK_GPIO_KEY_WAKEUP_TRIGGER
|
||||||
bool "Hardware supported wakeup (GPIO)"
|
bool "Hardware supported wakeup (GPIO)"
|
||||||
|
|
|
@ -6,4 +6,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
int zmk_pm_suspend_devices(void);
|
||||||
|
void zmk_pm_resume_devices(void);
|
||||||
|
|
||||||
int zmk_pm_soft_off(void);
|
int zmk_pm_soft_off(void);
|
|
@ -7,8 +7,6 @@
|
||||||
#include <zephyr/device.h>
|
#include <zephyr/device.h>
|
||||||
#include <zephyr/init.h>
|
#include <zephyr/init.h>
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/pm/device.h>
|
|
||||||
#include <zephyr/pm/device_runtime.h>
|
|
||||||
#include <zephyr/sys/poweroff.h>
|
#include <zephyr/sys/poweroff.h>
|
||||||
|
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
|
@ -20,69 +18,14 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
#include <zmk/events/position_state_changed.h>
|
#include <zmk/events/position_state_changed.h>
|
||||||
#include <zmk/events/sensor_event.h>
|
#include <zmk/events/sensor_event.h>
|
||||||
|
|
||||||
|
#include <zmk/pm.h>
|
||||||
|
|
||||||
#include <zmk/activity.h>
|
#include <zmk/activity.h>
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_USB_DEVICE_STACK)
|
#if IS_ENABLED(CONFIG_USB_DEVICE_STACK)
|
||||||
#include <zmk/usb.h>
|
#include <zmk/usb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Reimplement some of the device work from Zephyr PM to work with the new `sys_poweroff` API.
|
|
||||||
// TODO: Tweak this to smarter runtime PM of subsystems on sleep.
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM_DEVICE
|
|
||||||
TYPE_SECTION_START_EXTERN(const struct device *, zmk_pm_device_slots);
|
|
||||||
|
|
||||||
#if !defined(CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE)
|
|
||||||
/* Number of devices successfully suspended. */
|
|
||||||
static size_t zmk_num_susp;
|
|
||||||
|
|
||||||
static int zmk_pm_suspend_devices(void) {
|
|
||||||
const struct device *devs;
|
|
||||||
size_t devc;
|
|
||||||
|
|
||||||
devc = z_device_get_all_static(&devs);
|
|
||||||
|
|
||||||
zmk_num_susp = 0;
|
|
||||||
|
|
||||||
for (const struct device *dev = devs + devc - 1; dev >= devs; dev--) {
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ignore uninitialized devices, busy devices, wake up sources, and
|
|
||||||
* devices with runtime PM enabled.
|
|
||||||
*/
|
|
||||||
if (!device_is_ready(dev) || pm_device_is_busy(dev) || pm_device_state_is_locked(dev) ||
|
|
||||||
pm_device_wakeup_is_enabled(dev) || pm_device_runtime_is_enabled(dev)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND);
|
|
||||||
/* ignore devices not supporting or already at the given state */
|
|
||||||
if ((ret == -ENOSYS) || (ret == -ENOTSUP) || (ret == -EALREADY)) {
|
|
||||||
continue;
|
|
||||||
} else if (ret < 0) {
|
|
||||||
LOG_ERR("Device %s did not enter %s state (%d)", dev->name,
|
|
||||||
pm_device_state_str(PM_DEVICE_STATE_SUSPENDED), ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
TYPE_SECTION_START(zmk_pm_device_slots)[zmk_num_susp] = dev;
|
|
||||||
zmk_num_susp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void zmk_pm_resume_devices(void) {
|
|
||||||
for (int i = (zmk_num_susp - 1); i >= 0; i--) {
|
|
||||||
pm_device_action_run(TYPE_SECTION_START(zmk_pm_device_slots)[i], PM_DEVICE_ACTION_RESUME);
|
|
||||||
}
|
|
||||||
|
|
||||||
zmk_num_susp = 0;
|
|
||||||
}
|
|
||||||
#endif /* !CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE */
|
|
||||||
#endif /* CONFIG_PM_DEVICE */
|
|
||||||
|
|
||||||
bool is_usb_power_present(void) {
|
bool is_usb_power_present(void) {
|
||||||
#if IS_ENABLED(CONFIG_USB_DEVICE_STACK)
|
#if IS_ENABLED(CONFIG_USB_DEVICE_STACK)
|
||||||
return zmk_usb_is_powered();
|
return zmk_usb_is_powered();
|
||||||
|
|
|
@ -64,7 +64,7 @@ static const struct behavior_driver_api behavior_soft_off_driver_api = {
|
||||||
}; \
|
}; \
|
||||||
static struct behavior_soft_off_data bso_data_##n = {}; \
|
static struct behavior_soft_off_data bso_data_##n = {}; \
|
||||||
BEHAVIOR_DT_INST_DEFINE(0, behavior_soft_off_init, NULL, &bso_data_##n, &bso_config_##n, \
|
BEHAVIOR_DT_INST_DEFINE(0, behavior_soft_off_init, NULL, &bso_data_##n, &bso_config_##n, \
|
||||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
|
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
|
||||||
&behavior_soft_off_driver_api);
|
&behavior_soft_off_driver_api);
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(BSO_INST)
|
DT_INST_FOREACH_STATUS_OKAY(BSO_INST)
|
||||||
|
|
68
app/src/pm.c
68
app/src/pm.c
|
@ -8,13 +8,72 @@
|
||||||
#include <zephyr/devicetree.h>
|
#include <zephyr/devicetree.h>
|
||||||
#include <zephyr/init.h>
|
#include <zephyr/init.h>
|
||||||
#include <zephyr/pm/device.h>
|
#include <zephyr/pm/device.h>
|
||||||
|
#include <zephyr/pm/device_runtime.h>
|
||||||
#include <zephyr/pm/pm.h>
|
#include <zephyr/pm/pm.h>
|
||||||
|
#include <zephyr/sys/poweroff.h>
|
||||||
|
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
#include <zmk/endpoints.h>
|
#include <zmk/endpoints.h>
|
||||||
|
|
||||||
|
// Reimplement some of the device work from Zephyr PM to work with the new `sys_poweroff` API.
|
||||||
|
// TODO: Tweak this to smarter runtime PM of subsystems on sleep.
|
||||||
|
|
||||||
|
#ifdef CONFIG_ZMK_PM_DEVICE_SUSPEND_RESUME
|
||||||
|
TYPE_SECTION_START_EXTERN(const struct device *, zmk_pm_device_slots);
|
||||||
|
|
||||||
|
#if !defined(CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE)
|
||||||
|
/* Number of devices successfully suspended. */
|
||||||
|
static size_t zmk_num_susp;
|
||||||
|
|
||||||
|
int zmk_pm_suspend_devices(void) {
|
||||||
|
const struct device *devs;
|
||||||
|
size_t devc;
|
||||||
|
|
||||||
|
devc = z_device_get_all_static(&devs);
|
||||||
|
|
||||||
|
zmk_num_susp = 0;
|
||||||
|
|
||||||
|
for (const struct device *dev = devs + devc - 1; dev >= devs; dev--) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ignore uninitialized devices, busy devices, wake up sources, and
|
||||||
|
* devices with runtime PM enabled.
|
||||||
|
*/
|
||||||
|
if (!device_is_ready(dev) || pm_device_is_busy(dev) || pm_device_state_is_locked(dev) ||
|
||||||
|
pm_device_wakeup_is_enabled(dev) || pm_device_runtime_is_enabled(dev)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND);
|
||||||
|
/* ignore devices not supporting or already at the given state */
|
||||||
|
if ((ret == -ENOSYS) || (ret == -ENOTSUP) || (ret == -EALREADY)) {
|
||||||
|
continue;
|
||||||
|
} else if (ret < 0) {
|
||||||
|
LOG_ERR("Device %s did not enter %s state (%d)", dev->name,
|
||||||
|
pm_device_state_str(PM_DEVICE_STATE_SUSPENDED), ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE_SECTION_START(zmk_pm_device_slots)[zmk_num_susp] = dev;
|
||||||
|
zmk_num_susp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void zmk_pm_resume_devices(void) {
|
||||||
|
for (int i = (zmk_num_susp - 1); i >= 0; i--) {
|
||||||
|
pm_device_action_run(TYPE_SECTION_START(zmk_pm_device_slots)[i], PM_DEVICE_ACTION_RESUME);
|
||||||
|
}
|
||||||
|
|
||||||
|
zmk_num_susp = 0;
|
||||||
|
}
|
||||||
|
#endif /* !CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE */
|
||||||
|
#endif /* CONFIG_ZMK_PM_DEVICE_SUSPEND_RESUME */
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ZMK_PM_SOFT_OFF)
|
#if IS_ENABLED(CONFIG_ZMK_PM_SOFT_OFF)
|
||||||
|
|
||||||
#define HAS_WAKERS DT_HAS_COMPAT_STATUS_OKAY(zmk_soft_off_wakeup_sources)
|
#define HAS_WAKERS DT_HAS_COMPAT_STATUS_OKAY(zmk_soft_off_wakeup_sources)
|
||||||
|
@ -64,8 +123,15 @@ int zmk_pm_soft_off(void) {
|
||||||
}
|
}
|
||||||
#endif // HAS_WAKERS
|
#endif // HAS_WAKERS
|
||||||
|
|
||||||
|
int err = zmk_pm_suspend_devices();
|
||||||
|
if (err < 0) {
|
||||||
|
zmk_pm_resume_devices();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
LOG_DBG("soft-off: go to sleep");
|
LOG_DBG("soft-off: go to sleep");
|
||||||
return pm_state_force(0U, &(struct pm_state_info){PM_STATE_SOFT_OFF, 0, 0});
|
sys_poweroff();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // IS_ENABLED(CONFIG_ZMK_PM_SOFT_OFF)
|
#endif // IS_ENABLED(CONFIG_ZMK_PM_SOFT_OFF)
|
Loading…
Add table
Reference in a new issue