summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Winans <nick@winans.codes>2020-12-15 13:22:16 -0600
committerPete Johanson <peter@peterjohanson.com>2020-12-29 08:30:57 -0500
commit43f6d798be70ef247b0717730ec34202cb81e96d (patch)
tree9b0ebe807d6aa924ec9c9f2fdb41a2ac6a926bcd
parent87dbd4ca28405ab3d17cf62f3df86581606279b7 (diff)
feat(ext-power): Cut power when PM is sleeping
-rw-r--r--app/Kconfig3
-rw-r--r--app/src/ext_power_generic.c46
-rw-r--r--app/src/power.c4
3 files changed, 53 insertions, 0 deletions
diff --git a/app/Kconfig b/app/Kconfig
index acb288c..4341df1 100644
--- a/app/Kconfig
+++ b/app/Kconfig
@@ -234,6 +234,9 @@ choice SYS_PM_POLICY
default SYS_PM_POLICY_APP
endchoice
+config DEVICE_POWER_MANAGEMENT
+ default y
+
config ZMK_IDLE_SLEEP_TIMEOUT
int "Milliseconds of inactivity before entering deep sleep"
default 900000
diff --git a/app/src/ext_power_generic.c b/app/src/ext_power_generic.c
index 7e42d49..c2e89ab 100644
--- a/app/src/ext_power_generic.c
+++ b/app/src/ext_power_generic.c
@@ -31,6 +31,9 @@ struct ext_power_generic_data {
#if IS_ENABLED(CONFIG_SETTINGS)
bool settings_init;
#endif
+#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
+ uint32_t pm_state;
+#endif
};
#if IS_ENABLED(CONFIG_SETTINGS)
@@ -139,6 +142,10 @@ static int ext_power_generic_init(const struct device *dev) {
return -EIO;
}
+#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
+ data->pm_state = DEVICE_PM_ACTIVE_STATE;
+#endif
+
#if IS_ENABLED(CONFIG_SETTINGS)
settings_subsys_init();
@@ -167,6 +174,39 @@ static int ext_power_generic_init(const struct device *dev) {
return 0;
}
+#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
+static int ext_power_generic_pm_control(const struct device *dev, uint32_t ctrl_command,
+ void *context, device_pm_cb cb, void *arg) {
+ int rc;
+ struct ext_power_generic_data *data = dev->driver_data;
+
+ switch (ctrl_command) {
+ case DEVICE_PM_SET_POWER_STATE:
+ if (*((uint32_t *)context) == DEVICE_PM_ACTIVE_STATE) {
+ data->pm_state = DEVICE_PM_ACTIVE_STATE;
+ rc = 0;
+ } else {
+ ext_power_generic_disable(dev);
+ data->pm_state = DEVICE_PM_LOW_POWER_STATE;
+ rc = 0;
+ }
+ break;
+ case DEVICE_PM_GET_POWER_STATE:
+ *((uint32_t *)context) = data->pm_state;
+ rc = 0;
+ break;
+ default:
+ rc = -EINVAL;
+ }
+
+ if (cb != NULL) {
+ cb(dev, rc, context, arg);
+ }
+
+ return rc;
+}
+#endif /* CONFIG_DEVICE_POWER_MANAGEMENT */
+
static const struct ext_power_generic_config config = {
.label = DT_INST_GPIO_LABEL(0, control_gpios),
.pin = DT_INST_GPIO_PIN(0, control_gpios),
@@ -183,7 +223,13 @@ static const struct ext_power_api api = {.enable = ext_power_generic_enable,
.disable = ext_power_generic_disable,
.get = ext_power_generic_get};
+#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
+DEVICE_DEFINE(ext_power_generic, DT_INST_LABEL(0), ext_power_generic_init,
+ &ext_power_generic_pm_control, &data, &config, APPLICATION,
+ CONFIG_APPLICATION_INIT_PRIORITY, &api);
+#else
DEVICE_AND_API_INIT(ext_power_generic, DT_INST_LABEL(0), ext_power_generic_init, &data, &config,
APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY, &api);
+#endif /* CONFIG_DEVICE_POWER_MANAGEMENT */
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
diff --git a/app/src/power.c b/app/src/power.c
index d014a52..4af18cf 100644
--- a/app/src/power.c
+++ b/app/src/power.c
@@ -34,3 +34,7 @@ enum power_states sys_pm_policy_next_state(int32_t ticks) {
return SYS_POWER_STATE_ACTIVE;
}
+
+bool sys_pm_policy_low_power_devices(enum power_states pm_state) {
+ return sys_pm_is_sleep_state(pm_state);
+} \ No newline at end of file