Skip to content

Commit

Permalink
fix: Adjustments for Zephyr 3.5.
Browse files Browse the repository at this point in the history
  • Loading branch information
petejohanson committed Feb 20, 2024
1 parent 57d4243 commit c3281e9
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 61 deletions.
6 changes: 6 additions & 0 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ config ZMK_SLEEP
bool "Enable deep sleep support"
depends on HAS_POWEROFF
select POWEROFF
select ZMK_PM_DEVICE_SUSPEND_RESUME
imply USB

if ZMK_SLEEP
Expand All @@ -412,10 +413,15 @@ config ZMK_EXT_POWER
config ZMK_PM
bool

config ZMK_PM_DEVICE_SUSPEND_RESUME
bool
select ZMK_PM

config ZMK_PM_SOFT_OFF
bool "Soft-off support"
select ZMK_PM
select PM_DEVICE
select ZMK_PM_DEVICE_SUSPEND_RESUME

config ZMK_GPIO_KEY_WAKEUP_TRIGGER
bool "Hardware supported wakeup (GPIO)"
Expand Down
3 changes: 3 additions & 0 deletions app/include/zmk/pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@

#pragma once

int zmk_pm_suspend_devices(void);
void zmk_pm_resume_devices(void);

int zmk_pm_soft_off(void);
61 changes: 2 additions & 59 deletions app/src/activity.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/kernel.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/sys/poweroff.h>

#include <zephyr/logging/log.h>
Expand All @@ -20,69 +18,14 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/events/position_state_changed.h>
#include <zmk/events/sensor_event.h>

#include <zmk/pm.h>

#include <zmk/activity.h>

#if IS_ENABLED(CONFIG_USB_DEVICE_STACK)
#include <zmk/usb.h>
#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) {
#if IS_ENABLED(CONFIG_USB_DEVICE_STACK)
return zmk_usb_is_powered();
Expand Down
2 changes: 1 addition & 1 deletion app/src/behaviors/behavior_soft_off.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static const struct behavior_driver_api behavior_soft_off_driver_api = {
}; \
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, \
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
&behavior_soft_off_driver_api);

DT_INST_FOREACH_STATUS_OKAY(BSO_INST)
68 changes: 67 additions & 1 deletion app/src/pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,72 @@
#include <zephyr/devicetree.h>
#include <zephyr/init.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/pm/pm.h>
#include <zephyr/sys/poweroff.h>

#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);

#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)

#define HAS_WAKERS DT_HAS_COMPAT_STATUS_OKAY(zmk_soft_off_wakeup_sources)
Expand Down Expand Up @@ -64,8 +123,15 @@ int zmk_pm_soft_off(void) {
}
#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");
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)

0 comments on commit c3281e9

Please sign in to comment.