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
This commit is contained in:
parent
76a6d7b4c5
commit
093719a3b8
2 changed files with 95 additions and 12 deletions
|
@ -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) */
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in a new issue