summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorNick <nick.win999@gmail.com>2020-11-28 00:19:44 -0600
committerPete Johanson <peter@peterjohanson.com>2020-11-28 01:44:35 -0500
commit093719a3b85774326f1ffaf3a907b5186250ceee (patch)
tree1c1fdfed65ad2f071d04545ab4f6bc8b0c7c9908 /app
parent76a6d7b4c5c18b64f36a421f3faca81f311ed465 (diff)
feat: Add settings support for external power
fix: clang-format and setting state variable fix: Fix startup settings configuration fix(ext_power): Add static to state fix(ext_power): Set default settings value Use driver data status instead of global file state
Diffstat (limited to 'app')
-rw-r--r--app/src/ext_power_generic.c99
-rw-r--r--app/src/main.c8
2 files changed, 95 insertions, 12 deletions
diff --git a/app/src/ext_power_generic.c b/app/src/ext_power_generic.c
index 4817030..76ee00c 100644
--- a/app/src/ext_power_generic.c
+++ b/app/src/ext_power_generic.c
@@ -6,8 +6,11 @@
#define DT_DRV_COMPAT zmk_ext_power_generic
+#include <stdio.h>
#include <device.h>
#include <init.h>
+#include <kernel.h>
+#include <settings/settings.h>
#include <drivers/gpio.h>
#include <drivers/ext_power.h>
@@ -25,8 +28,33 @@ struct ext_power_generic_config {
struct ext_power_generic_data {
struct device *gpio;
bool status;
+#if IS_ENABLED(CONFIG_SETTINGS)
+ bool settings_init;
+#endif
};
+#if IS_ENABLED(CONFIG_SETTINGS)
+static void ext_power_save_state_work(struct k_work *work) {
+ char setting_path[40];
+ struct device *ext_power = device_get_binding(DT_INST_LABEL(0));
+ struct ext_power_generic_data *data = ext_power->driver_data;
+
+ snprintf(setting_path, 40, "ext_power/state/%s", DT_INST_LABEL(0));
+ settings_save_one(setting_path, &data->status, sizeof(data->status));
+}
+
+static struct k_delayed_work ext_power_save_work;
+#endif
+
+int ext_power_save_state() {
+#if IS_ENABLED(CONFIG_SETTINGS)
+ k_delayed_work_cancel(&ext_power_save_work);
+ return k_delayed_work_submit(&ext_power_save_work, K_MINUTES(1));
+#else
+ return 0;
+#endif
+}
+
static int ext_power_generic_enable(struct device *dev) {
struct ext_power_generic_data *data = dev->driver_data;
const struct ext_power_generic_config *config = dev->config_info;
@@ -36,7 +64,7 @@ static int ext_power_generic_enable(struct device *dev) {
return -EIO;
}
data->status = true;
- return 0;
+ return ext_power_save_state();
}
static int ext_power_generic_disable(struct device *dev) {
@@ -48,7 +76,7 @@ static int ext_power_generic_disable(struct device *dev) {
return -EIO;
}
data->status = false;
- return 0;
+ return ext_power_save_state();
}
static int ext_power_generic_get(struct device *dev) {
@@ -56,6 +84,46 @@ static int ext_power_generic_get(struct device *dev) {
return data->status;
}
+#if IS_ENABLED(CONFIG_SETTINGS)
+static int ext_power_settings_set(const char *name, size_t len, settings_read_cb read_cb,
+ void *cb_arg) {
+ const char *next;
+ int rc;
+
+ if (settings_name_steq(name, DT_INST_LABEL(0), &next) && !next) {
+ struct device *ext_power = device_get_binding(DT_INST_LABEL(0));
+ struct ext_power_generic_data *data = ext_power->driver_data;
+
+ if (len != sizeof(data->status)) {
+ return -EINVAL;
+ }
+
+ rc = read_cb(cb_arg, &data->status, sizeof(data->status));
+ if (rc >= 0) {
+ data->settings_init = true;
+
+ if (ext_power == NULL) {
+ LOG_ERR("Unable to retrieve ext_power device: %s", DT_INST_LABEL(0));
+ return -EIO;
+ }
+
+ if (data->status) {
+ ext_power_generic_enable(ext_power);
+ } else {
+ ext_power_generic_disable(ext_power);
+ }
+
+ return 0;
+ }
+ return rc;
+ }
+ return -ENOENT;
+}
+
+struct settings_handler ext_power_conf = {.name = "ext_power/state",
+ .h_set = ext_power_settings_set};
+#endif
+
static int ext_power_generic_init(struct device *dev) {
struct ext_power_generic_data *data = dev->driver_data;
const struct ext_power_generic_config *config = dev->config_info;
@@ -71,6 +139,24 @@ static int ext_power_generic_init(struct device *dev) {
return -EIO;
}
+#if IS_ENABLED(CONFIG_SETTINGS)
+ settings_register(&ext_power_conf);
+ k_delayed_work_init(&ext_power_save_work, ext_power_save_state_work);
+
+ // Set default value (on) if settings isn't set
+ settings_load_subtree("ext_power");
+ if (!data->settings_init) {
+
+ data->status = true;
+ k_delayed_work_submit(&ext_power_save_work, K_NO_WAIT);
+
+ ext_power_enable(dev);
+ }
+#else
+ // Default to the ext_power being open when no settings
+ ext_power_enable(dev);
+#endif
+
return 0;
}
@@ -79,13 +165,18 @@ static const struct ext_power_generic_config config = {
.pin = DT_INST_GPIO_PIN(0, control_gpios),
.flags = DT_INST_GPIO_FLAGS(0, control_gpios)};
-static struct ext_power_generic_data data = {.status = false};
+static struct ext_power_generic_data data = {
+ .status = false,
+#if IS_ENABLED(CONFIG_SETTINGS)
+ .settings_init = false,
+#endif
+};
static const struct ext_power_api api = {.enable = ext_power_generic_enable,
.disable = ext_power_generic_disable,
.get = ext_power_generic_get};
DEVICE_AND_API_INIT(ext_power_generic, DT_INST_LABEL(0), ext_power_generic_init, &data, &config,
- APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &api);
+ APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY, &api);
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
diff --git a/app/src/main.c b/app/src/main.c
index 0551356..eb0275b 100644
--- a/app/src/main.c
+++ b/app/src/main.c
@@ -20,20 +20,12 @@ LOG_MODULE_REGISTER(zmk, CONFIG_ZMK_LOG_LEVEL);
#define ZMK_KSCAN_DEV DT_LABEL(ZMK_MATRIX_NODE_ID)
void main(void) {
- struct device *ext_power;
LOG_INF("Welcome to ZMK!\n");
if (zmk_kscan_init(ZMK_KSCAN_DEV) != 0) {
return;
}
- // Enable the external VCC output
- ext_power = device_get_binding("EXT_POWER");
- if (ext_power != NULL) {
- const struct ext_power_api *ext_power_api = ext_power->driver_api;
- ext_power_api->enable(ext_power);
- }
-
#ifdef CONFIG_ZMK_DISPLAY
zmk_display_init();