fix: Cleanups of sideband and direct kscan from review.
* Add dedicated init priority for the sideband kscan. * Refactor sideband code for clarity. * Tweaks to direct kscan for clarity. * Make sideband behavior row optional for brevity. * Allow overriding ZMK Uno sideband behaviors.
This commit is contained in:
parent
4198fac90f
commit
5d960a758f
7 changed files with 78 additions and 61 deletions
|
@ -518,6 +518,15 @@ config ZMK_KSCAN_SIDEBAND_BEHAVIORS
|
||||||
depends on DT_HAS_ZMK_KSCAN_SIDEBAND_BEHAVIORS_ENABLED
|
depends on DT_HAS_ZMK_KSCAN_SIDEBAND_BEHAVIORS_ENABLED
|
||||||
select KSCAN
|
select KSCAN
|
||||||
|
|
||||||
|
if ZMK_KSCAN_SIDEBAND_BEHAVIORS
|
||||||
|
|
||||||
|
config ZMK_KSCAN_SIDEBAND_BEHAVIORS_INIT_PRIORITY
|
||||||
|
int "Keyboard scan sideband behaviors driver init priority"
|
||||||
|
# The default kscan init priority is 90, so be sure we are lower.
|
||||||
|
default 95
|
||||||
|
|
||||||
|
endif # ZMK_KSCAN_SIDEBAND_BEHAVIORS
|
||||||
|
|
||||||
menu "Logging"
|
menu "Logging"
|
||||||
|
|
||||||
config ZMK_LOGGING_MINIMAL
|
config ZMK_LOGGING_MINIMAL
|
||||||
|
|
|
@ -11,21 +11,17 @@
|
||||||
#include <dt-bindings/zmk/ext_power.h>
|
#include <dt-bindings/zmk/ext_power.h>
|
||||||
#include <dt-bindings/zmk/rgb.h>
|
#include <dt-bindings/zmk/rgb.h>
|
||||||
|
|
||||||
// Uncomment the following block if using the "Direct Wire" jumper to switch the matrix to a direct wire.
|
// Uncomment the following lines if using the "Direct Wire" jumper to switch the matrix to a direct wire.
|
||||||
|
|
||||||
/* :REMOVE ME
|
// &kscan_direct { status = "okay"; };
|
||||||
|
// &kscan_matrix { status = "disabled"; };
|
||||||
|
|
||||||
&kscan_direct { status = "okay"; };
|
// / {
|
||||||
&kscan_matrix { status = "disabled"; };
|
// chosen {
|
||||||
|
// zmk,matrix-transform = &direct_matrix_transform;
|
||||||
/ {
|
// zmk,kscan = &kscan_direct;
|
||||||
chosen {
|
// };
|
||||||
zmk,matrix-transform = &direct_matrix_transform;
|
// };
|
||||||
zmk,kscan = &kscan_direct;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
REMOVE ME: */
|
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
keymap {
|
keymap {
|
||||||
|
|
|
@ -40,20 +40,17 @@
|
||||||
compatible = "zmk,kscan-sideband-behaviors";
|
compatible = "zmk,kscan-sideband-behaviors";
|
||||||
kscan = <&kscan_sp3t_toggle>;
|
kscan = <&kscan_sp3t_toggle>;
|
||||||
|
|
||||||
usb {
|
first_toggle_sideband: first_toggle_sideband {
|
||||||
row = <0>;
|
|
||||||
column = <0>;
|
column = <0>;
|
||||||
bindings = <&out OUT_USB>;
|
bindings = <&out OUT_USB>;
|
||||||
};
|
};
|
||||||
|
|
||||||
ble_zero {
|
second_toggle_sideband: second_toggle_sideband {
|
||||||
row = <0>;
|
|
||||||
column = <1>;
|
column = <1>;
|
||||||
bindings = <&ble_zero>;
|
bindings = <&ble_zero>;
|
||||||
};
|
};
|
||||||
|
|
||||||
ble_one {
|
third_toggle_sideband: third_toggle_sideband {
|
||||||
row = <0>;
|
|
||||||
column = <2>;
|
column = <2>;
|
||||||
bindings = <&ble_one>;
|
bindings = <&ble_one>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,21 +12,18 @@
|
||||||
#include <dt-bindings/zmk/outputs.h>
|
#include <dt-bindings/zmk/outputs.h>
|
||||||
#include <dt-bindings/zmk/rgb.h>
|
#include <dt-bindings/zmk/rgb.h>
|
||||||
|
|
||||||
// Uncomment the following block if using the "Direct Wire" jumper to switch the matrix to a direct wire.
|
// Uncomment the following lines if using the "Direct Wire" jumper to switch the matrix to a direct wire.
|
||||||
|
|
||||||
/* :REMOVE ME
|
|
||||||
|
|
||||||
&kscan_direct { status = "okay"; };
|
// &kscan_direct { status = "okay"; };
|
||||||
&kscan_matrix { status = "disabled"; };
|
// &kscan_matrix { status = "disabled"; };
|
||||||
|
|
||||||
/ {
|
// / {
|
||||||
chosen {
|
// chosen {
|
||||||
zmk,matrix-transform = &split_direct_matrix_transform;
|
// zmk,matrix-transform = &split_direct_matrix_transform;
|
||||||
zmk,kscan = &kscan_direct_comp;
|
// zmk,kscan = &kscan_direct_comp;
|
||||||
};
|
// };
|
||||||
};
|
// };
|
||||||
|
|
||||||
REMOVE ME: */
|
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
description: |
|
description: |
|
||||||
kscan sideband behavior runner. Only basic system behavior should be used,
|
kscan sideband behavior runner. Only basic system behaviors should be used,
|
||||||
since no keymap processing occurs when using them.
|
since no keymap processing occurs when using them. Primarily, that means avoiding
|
||||||
|
using tap-holds, sticky keys, etc. as sideband behaviors.
|
||||||
|
|
||||||
compatible: "zmk,kscan-sideband-behaviors"
|
compatible: "zmk,kscan-sideband-behaviors"
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ child-binding:
|
||||||
properties:
|
properties:
|
||||||
row:
|
row:
|
||||||
type: int
|
type: int
|
||||||
required: true
|
default: 0
|
||||||
column:
|
column:
|
||||||
type: int
|
type: int
|
||||||
required: true
|
required: true
|
||||||
|
|
|
@ -46,7 +46,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, input_gpios), (DT_INST_PROP_LEN(n, input_gpios)), \
|
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, input_gpios), (DT_INST_PROP_LEN(n, input_gpios)), \
|
||||||
(DT_INST_PROP_LEN(n, input_keys)))
|
(DT_INST_PROP_LEN(n, input_keys)))
|
||||||
|
|
||||||
#define KSCAN_DIRECT_INPUT_CFG_INIT(idx, inst_idx) \
|
#define KSCAN_GPIO_DIRECT_INPUT_CFG_INIT(idx, inst_idx) \
|
||||||
KSCAN_GPIO_GET_BY_IDX(DT_DRV_INST(inst_idx), input_gpios, idx)
|
KSCAN_GPIO_GET_BY_IDX(DT_DRV_INST(inst_idx), input_gpios, idx)
|
||||||
#define KSCAN_KEY_DIRECT_INPUT_CFG_INIT(idx, inst_idx) \
|
#define KSCAN_KEY_DIRECT_INPUT_CFG_INIT(idx, inst_idx) \
|
||||||
KSCAN_GPIO_GET_BY_IDX(DT_INST_PROP_BY_IDX(inst_idx, input_keys, idx), gpios, 0)
|
KSCAN_GPIO_GET_BY_IDX(DT_INST_PROP_BY_IDX(inst_idx, input_keys, idx), gpios, 0)
|
||||||
|
@ -353,7 +353,7 @@ static const struct kscan_driver_api kscan_direct_api = {
|
||||||
\
|
\
|
||||||
static struct kscan_gpio kscan_direct_inputs_##n[] = { \
|
static struct kscan_gpio kscan_direct_inputs_##n[] = { \
|
||||||
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, input_gpios), \
|
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, input_gpios), \
|
||||||
(LISTIFY(INST_INPUTS_LEN(n), KSCAN_DIRECT_INPUT_CFG_INIT, (, ), n)), \
|
(LISTIFY(INST_INPUTS_LEN(n), KSCAN_GPIO_DIRECT_INPUT_CFG_INIT, (, ), n)), \
|
||||||
(LISTIFY(INST_INPUTS_LEN(n), KSCAN_KEY_DIRECT_INPUT_CFG_INIT, (, ), n)))}; \
|
(LISTIFY(INST_INPUTS_LEN(n), KSCAN_KEY_DIRECT_INPUT_CFG_INIT, (, ), n)))}; \
|
||||||
\
|
\
|
||||||
static struct zmk_debounce_state kscan_direct_state_##n[INST_INPUTS_LEN(n)]; \
|
static struct zmk_debounce_state kscan_direct_state_##n[INST_INPUTS_LEN(n)]; \
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
struct ksbb_entry {
|
struct ksbb_entry {
|
||||||
|
struct zmk_behavior_binding binding;
|
||||||
uint8_t row;
|
uint8_t row;
|
||||||
uint8_t column;
|
uint8_t column;
|
||||||
struct zmk_behavior_binding binding;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ksbb_config {
|
struct ksbb_config {
|
||||||
|
@ -39,23 +39,46 @@ struct ksbb_data {
|
||||||
|
|
||||||
// The kscan callback has no context with it, so we keep a static array of all possible
|
// The kscan callback has no context with it, so we keep a static array of all possible
|
||||||
// KSBBs to check when a kscan callback from the "wrapped" inner kscan fires.
|
// KSBBs to check when a kscan callback from the "wrapped" inner kscan fires.
|
||||||
static const struct device *ksbbs[DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT)] = {
|
static const struct device *ksbbs[] = {DT_INST_FOREACH_STATUS_OKAY(GET_KSBB_DEV)};
|
||||||
DT_INST_FOREACH_STATUS_OKAY(GET_KSBB_DEV)};
|
|
||||||
|
|
||||||
void ksbb_inner_kscan_callback(const struct device *dev, uint32_t row, uint32_t column,
|
int find_ksbb_for_inner(const struct device *inner_dev, const struct device **ksbb_dev) {
|
||||||
bool pressed) {
|
|
||||||
for (int i = 0; i < ARRAY_SIZE(ksbbs); i++) {
|
for (int i = 0; i < ARRAY_SIZE(ksbbs); i++) {
|
||||||
const struct device *ksbb = ksbbs[i];
|
const struct device *ksbb = ksbbs[i];
|
||||||
const struct ksbb_config *cfg = ksbb->config;
|
const struct ksbb_config *cfg = ksbb->config;
|
||||||
struct ksbb_data *data = ksbb->data;
|
|
||||||
|
|
||||||
if (cfg->kscan != dev) {
|
if (cfg->kscan == inner_dev) {
|
||||||
continue;
|
*ksbb_dev = ksbb;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
int find_sideband_behavior(const struct device *dev, uint32_t row, uint32_t column,
|
||||||
|
struct ksbb_entry **entry) {
|
||||||
|
const struct ksbb_config *cfg = dev->config;
|
||||||
|
|
||||||
for (int e = 0; e < cfg->entries_len; e++) {
|
for (int e = 0; e < cfg->entries_len; e++) {
|
||||||
struct ksbb_entry *entry = &cfg->entries[e];
|
struct ksbb_entry *candidate = &cfg->entries[e];
|
||||||
if (entry->row == row && entry->column == column) {
|
|
||||||
|
if (candidate->row == row && candidate->column == column) {
|
||||||
|
*entry = candidate;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ksbb_inner_kscan_callback(const struct device *dev, uint32_t row, uint32_t column,
|
||||||
|
bool pressed) {
|
||||||
|
struct ksbb_entry *entry = NULL;
|
||||||
|
const struct device *ksbb = NULL;
|
||||||
|
|
||||||
|
if (find_ksbb_for_inner(dev, &ksbb) >= 0) {
|
||||||
|
struct ksbb_data *data = ksbb->data;
|
||||||
|
if (find_sideband_behavior(ksbb, row, column, &entry) >= 0) {
|
||||||
struct zmk_behavior_binding_event event = {.position = INT32_MAX,
|
struct zmk_behavior_binding_event event = {.position = INT32_MAX,
|
||||||
.timestamp = k_uptime_get()};
|
.timestamp = k_uptime_get()};
|
||||||
|
|
||||||
|
@ -64,8 +87,6 @@ void ksbb_inner_kscan_callback(const struct device *dev, uint32_t row, uint32_t
|
||||||
} else {
|
} else {
|
||||||
behavior_keymap_binding_released(&entry->binding, event);
|
behavior_keymap_binding_released(&entry->binding, event);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->enabled && data->callback) {
|
if (data->enabled && data->callback) {
|
||||||
|
@ -78,10 +99,6 @@ static int ksbb_configure(const struct device *dev, kscan_callback_t callback) {
|
||||||
const struct ksbb_config *cfg = dev->config;
|
const struct ksbb_config *cfg = dev->config;
|
||||||
struct ksbb_data *data = dev->data;
|
struct ksbb_data *data = dev->data;
|
||||||
|
|
||||||
if (!callback) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->callback = callback;
|
data->callback = callback;
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_PM_DEVICE)
|
#if IS_ENABLED(CONFIG_PM_DEVICE)
|
||||||
|
@ -161,7 +178,7 @@ static int ksbb_pm_action(const struct device *dev, enum pm_device_action action
|
||||||
struct ksbb_data ksbb_data_##n = {}; \
|
struct ksbb_data ksbb_data_##n = {}; \
|
||||||
PM_DEVICE_DT_INST_DEFINE(n, ksbb_pm_action); \
|
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, \
|
DEVICE_DT_INST_DEFINE(n, ksbb_init, PM_DEVICE_DT_INST_GET(n), &ksbb_data_##n, \
|
||||||
&ksbb_config_##n, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
|
&ksbb_config_##n, POST_KERNEL, \
|
||||||
&ksbb_api);
|
CONFIG_ZMK_KSCAN_SIDEBAND_BEHAVIORS_INIT_PRIORITY, &ksbb_api);
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(KSBB_INST)
|
DT_INST_FOREACH_STATUS_OKAY(KSBB_INST)
|
||||||
|
|
Loading…
Add table
Reference in a new issue