forked from kofal.net/zmk
feat(kscan): More complete PM support to drivers.
* Update our GPIO kscan drivers to more completely support PM device, by doing proper hardare init/deinit in the PM action hook.
This commit is contained in:
committed by
Pete Johanson
parent
c5cca5b34f
commit
0438cb0ee5
@@ -26,6 +26,7 @@ struct ksbb_entry {
|
||||
|
||||
struct ksbb_config {
|
||||
const struct device *kscan;
|
||||
bool auto_enable;
|
||||
struct ksbb_entry *entries;
|
||||
size_t entries_len;
|
||||
};
|
||||
@@ -93,34 +94,65 @@ void ksbb_inner_kscan_callback(const struct device *dev, uint32_t row, uint32_t
|
||||
}
|
||||
|
||||
static int ksbb_configure(const struct device *dev, kscan_callback_t callback) {
|
||||
const struct ksbb_config *cfg = dev->config;
|
||||
struct ksbb_data *data = dev->data;
|
||||
|
||||
data->callback = callback;
|
||||
|
||||
#if IS_ENABLED(CONFIG_PM_DEVICE)
|
||||
if (pm_device_wakeup_is_enabled(dev) && pm_device_wakeup_is_capable(cfg->kscan)) {
|
||||
pm_device_wakeup_enable(cfg->kscan, true);
|
||||
}
|
||||
#endif // IS_ENABLED(CONFIG_PM_DEVICE)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ksbb_enable(const struct device *dev) {
|
||||
struct ksbb_data *data = dev->data;
|
||||
const struct ksbb_config *config = dev->config;
|
||||
data->enabled = true;
|
||||
|
||||
#if IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)
|
||||
if (!pm_device_runtime_is_enabled(dev) && pm_device_runtime_is_enabled(config->kscan)) {
|
||||
pm_device_runtime_get(config->kscan);
|
||||
}
|
||||
#elif IS_ENABLED(CONFIG_PM_DEVICE)
|
||||
pm_device_action_run(config->kscan, PM_DEVICE_ACTION_RESUME);
|
||||
#endif // IS_ENABLED(CONFIG_PM_DEVICE)
|
||||
|
||||
kscan_config(config->kscan, &ksbb_inner_kscan_callback);
|
||||
kscan_enable_callback(config->kscan);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ksbb_disable(const struct device *dev) {
|
||||
struct ksbb_data *data = dev->data;
|
||||
const struct ksbb_config *config = dev->config;
|
||||
data->enabled = false;
|
||||
|
||||
kscan_disable_callback(config->kscan);
|
||||
|
||||
#if IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)
|
||||
if (!pm_device_runtime_is_enabled(dev) && pm_device_runtime_is_enabled(config->kscan)) {
|
||||
pm_device_runtime_put(config->kscan);
|
||||
}
|
||||
#elif IS_ENABLED(CONFIG_PM_DEVICE)
|
||||
pm_device_action_run(config->kscan, PM_DEVICE_ACTION_SUSPEND);
|
||||
#endif // IS_ENABLED(CONFIG_PM_DEVICE)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_PM_DEVICE)
|
||||
|
||||
static int ksbb_pm_action(const struct device *dev, enum pm_device_action action) {
|
||||
switch (action) {
|
||||
case PM_DEVICE_ACTION_SUSPEND:
|
||||
return ksbb_disable(dev);
|
||||
case PM_DEVICE_ACTION_RESUME:
|
||||
return ksbb_enable(dev);
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_PM_DEVICE)
|
||||
|
||||
static int ksbb_init(const struct device *dev) {
|
||||
const struct ksbb_config *config = dev->config;
|
||||
|
||||
@@ -129,8 +161,16 @@ static int ksbb_init(const struct device *dev) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
kscan_config(config->kscan, &ksbb_inner_kscan_callback);
|
||||
kscan_enable_callback(config->kscan);
|
||||
if (config->auto_enable) {
|
||||
#if !IS_ENABLED(CONFIG_PM_DEVICE)
|
||||
kscan_config(config->kscan, &ksbb_inner_kscan_callback);
|
||||
kscan_enable_callback(config->kscan);
|
||||
#else
|
||||
ksbb_pm_action(dev, PM_DEVICE_ACTION_RESUME);
|
||||
} else {
|
||||
pm_device_init_suspended(dev);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -141,21 +181,6 @@ static const struct kscan_driver_api ksbb_api = {
|
||||
.disable_callback = ksbb_disable,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_PM_DEVICE)
|
||||
|
||||
static int ksbb_pm_action(const struct device *dev, enum pm_device_action action) {
|
||||
switch (action) {
|
||||
case PM_DEVICE_ACTION_SUSPEND:
|
||||
return ksbb_disable(dev);
|
||||
case PM_DEVICE_ACTION_RESUME:
|
||||
return ksbb_disable(dev);
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_PM_DEVICE)
|
||||
|
||||
#define ENTRY(e) \
|
||||
{ \
|
||||
.row = DT_PROP(e, row), .column = DT_PROP(e, column), \
|
||||
@@ -167,13 +192,14 @@ static int ksbb_pm_action(const struct device *dev, enum pm_device_action action
|
||||
DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP(n, ENTRY, (, ))}; \
|
||||
const struct ksbb_config ksbb_config_##n = { \
|
||||
.kscan = DEVICE_DT_GET(DT_INST_PHANDLE(n, kscan)), \
|
||||
.auto_enable = DT_INST_PROP_OR(n, auto_enable, false), \
|
||||
.entries = entries_##n, \
|
||||
.entries_len = ARRAY_SIZE(entries_##n), \
|
||||
}; \
|
||||
struct ksbb_data ksbb_data_##n = {}; \
|
||||
PM_DEVICE_DT_INST_DEFINE(n, ksbb_pm_action); \
|
||||
DEVICE_DT_INST_DEFINE(n, ksbb_init, PM_DEVICE_DT_INST_GET(n), &ksbb_data_##n, \
|
||||
&ksbb_config_##n, APPLICATION, \
|
||||
&ksbb_config_##n, POST_KERNEL, \
|
||||
CONFIG_ZMK_KSCAN_SIDEBAND_BEHAVIORS_INIT_PRIORITY, &ksbb_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(KSBB_INST)
|
||||
|
||||
Reference in New Issue
Block a user