19
19
LOG_MODULE_DECLARE (zmk , CONFIG_ZMK_LOG_LEVEL );
20
20
21
21
struct ksbb_entry {
22
+ struct zmk_behavior_binding binding ;
22
23
uint8_t row ;
23
24
uint8_t column ;
24
- struct zmk_behavior_binding binding ;
25
25
};
26
26
27
27
struct ksbb_config {
@@ -39,32 +39,53 @@ struct ksbb_data {
39
39
40
40
// The kscan callback has no context with it, so we keep a static array of all possible
41
41
// KSBBs to check when a kscan callback from the "wrapped" inner kscan fires.
42
- static const struct device * ksbbs [DT_NUM_INST_STATUS_OKAY (DT_DRV_COMPAT )] = {
43
- DT_INST_FOREACH_STATUS_OKAY (GET_KSBB_DEV )};
42
+ static const struct device * ksbbs [] = {DT_INST_FOREACH_STATUS_OKAY (GET_KSBB_DEV )};
44
43
45
- void ksbb_inner_kscan_callback (const struct device * dev , uint32_t row , uint32_t column ,
46
- bool pressed ) {
44
+ int find_ksbb_for_inner (const struct device * inner_dev , const struct device * * ksbb_dev ) {
47
45
for (int i = 0 ; i < ARRAY_SIZE (ksbbs ); i ++ ) {
48
46
const struct device * ksbb = ksbbs [i ];
49
47
const struct ksbb_config * cfg = ksbb -> config ;
50
- struct ksbb_data * data = ksbb -> data ;
51
48
52
- if (cfg -> kscan != dev ) {
53
- continue ;
49
+ if (cfg -> kscan == inner_dev ) {
50
+ * ksbb_dev = ksbb ;
51
+ return 0 ;
52
+ }
53
+ }
54
+
55
+ return - ENODEV ;
56
+ }
57
+
58
+ int find_sideband_behavior (const struct device * dev , uint32_t row , uint32_t column ,
59
+ struct ksbb_entry * * entry ) {
60
+ const struct ksbb_config * cfg = dev -> config ;
61
+
62
+ for (int e = 0 ; e < cfg -> entries_len ; e ++ ) {
63
+ struct ksbb_entry * candidate = & cfg -> entries [e ];
64
+
65
+ if (candidate -> row == row && candidate -> column == column ) {
66
+ * entry = candidate ;
67
+ return 0 ;
54
68
}
69
+ }
55
70
56
- for (int e = 0 ; e < cfg -> entries_len ; e ++ ) {
57
- struct ksbb_entry * entry = & cfg -> entries [e ];
58
- if (entry -> row == row && entry -> column == column ) {
59
- struct zmk_behavior_binding_event event = {.position = INT32_MAX ,
60
- .timestamp = k_uptime_get ()};
61
-
62
- if (pressed ) {
63
- behavior_keymap_binding_pressed (& entry -> binding , event );
64
- } else {
65
- behavior_keymap_binding_released (& entry -> binding , event );
66
- }
67
- return ;
71
+ return - ENODEV ;
72
+ }
73
+
74
+ void ksbb_inner_kscan_callback (const struct device * dev , uint32_t row , uint32_t column ,
75
+ bool pressed ) {
76
+ struct ksbb_entry * entry = NULL ;
77
+ const struct device * ksbb = NULL ;
78
+
79
+ if (find_ksbb_for_inner (dev , & ksbb ) >= 0 ) {
80
+ struct ksbb_data * data = ksbb -> data ;
81
+ if (find_sideband_behavior (ksbb , row , column , & entry ) >= 0 ) {
82
+ struct zmk_behavior_binding_event event = {.position = INT32_MAX ,
83
+ .timestamp = k_uptime_get ()};
84
+
85
+ if (pressed ) {
86
+ behavior_keymap_binding_pressed (& entry -> binding , event );
87
+ } else {
88
+ behavior_keymap_binding_released (& entry -> binding , event );
68
89
}
69
90
}
70
91
@@ -78,10 +99,6 @@ static int ksbb_configure(const struct device *dev, kscan_callback_t callback) {
78
99
const struct ksbb_config * cfg = dev -> config ;
79
100
struct ksbb_data * data = dev -> data ;
80
101
81
- if (!callback ) {
82
- return - EINVAL ;
83
- }
84
-
85
102
data -> callback = callback ;
86
103
87
104
#if IS_ENABLED (CONFIG_PM_DEVICE )
@@ -161,7 +178,7 @@ static int ksbb_pm_action(const struct device *dev, enum pm_device_action action
161
178
struct ksbb_data ksbb_data_##n = {}; \
162
179
PM_DEVICE_DT_INST_DEFINE(n, ksbb_pm_action); \
163
180
DEVICE_DT_INST_DEFINE(n, ksbb_init, PM_DEVICE_DT_INST_GET(n), &ksbb_data_##n, \
164
- &ksbb_config_##n, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
165
- &ksbb_api);
181
+ &ksbb_config_##n, POST_KERNEL, \
182
+ CONFIG_ZMK_KSCAN_SIDEBAND_BEHAVIORS_INIT_PRIORITY, &ksbb_api);
166
183
167
184
DT_INST_FOREACH_STATUS_OKAY (KSBB_INST )
0 commit comments