Skip to content

Commit 032f421

Browse files
committed
feat: Add input split support.
1 parent d94a109 commit 032f421

File tree

10 files changed

+458
-63
lines changed

10 files changed

+458
-63
lines changed

app/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ target_sources_ifdef(CONFIG_USB_DEVICE_STACK app PRIVATE src/events/usb_conn_sta
4242
target_sources(app PRIVATE src/behaviors/behavior_reset.c)
4343
target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/behaviors/behavior_ext_power.c)
4444
target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_SOFT_OFF app PRIVATE src/behaviors/behavior_soft_off.c)
45+
add_subdirectory_ifdef(CONFIG_ZMK_MOUSE src/mouse/)
4546
if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
4647
target_sources(app PRIVATE src/hid.c)
47-
add_subdirectory_ifdef(CONFIG_ZMK_MOUSE src/mouse/)
4848
target_sources(app PRIVATE src/behaviors/behavior_key_press.c)
4949
target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_KEY_TOGGLE app PRIVATE src/behaviors/behavior_key_toggle.c)
5050
target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_HOLD_TAP app PRIVATE src/behaviors/behavior_hold_tap.c)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
include: [base.yaml]
2+
3+
compatible: "zmk,input-split"
4+
5+
description: Device to wire up an input device for split use.
6+
7+
properties:
8+
reg:
9+
required: true
10+
11+
device:
12+
type: phandle
13+
14+
input-processors:
15+
type: phandle-array
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
* Copyright (c) 2024 The ZMK Contributors
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
7+
#pragma once
8+
9+
int zmk_input_split_report_peripheral_event(uint8_t reg, uint8_t type, uint16_t code, int32_t value,
10+
bool sync);

app/include/zmk/split/bluetooth/service.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,17 @@ struct zmk_split_run_behavior_payload {
3131
char behavior_dev[ZMK_SPLIT_RUN_BEHAVIOR_DEV_LEN];
3232
} __packed;
3333

34+
struct zmk_split_input_event_payload {
35+
uint8_t type;
36+
uint16_t code;
37+
uint32_t value;
38+
uint8_t sync;
39+
} __packed;
40+
3441
int zmk_split_bt_position_pressed(uint8_t position);
3542
int zmk_split_bt_position_released(uint8_t position);
3643
int zmk_split_bt_sensor_triggered(uint8_t sensor_index,
3744
const struct zmk_sensor_channel_data channel_data[],
3845
size_t channel_data_size);
46+
47+
int zmk_split_bt_report_input(uint8_t reg, uint8_t type, uint16_t code, int32_t value, bool sync);

app/include/zmk/split/bluetooth/uuid.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@
1919
#define ZMK_SPLIT_BT_CHAR_SENSOR_STATE_UUID ZMK_BT_SPLIT_UUID(0x00000003)
2020
#define ZMK_SPLIT_BT_UPDATE_HID_INDICATORS_UUID ZMK_BT_SPLIT_UUID(0x00000004)
2121
#define ZMK_SPLIT_BT_SELECT_PHYS_LAYOUT_UUID ZMK_BT_SPLIT_UUID(0x00000005)
22+
#define ZMK_SPLIT_BT_INPUT_EVENT_UUID ZMK_BT_SPLIT_UUID(0x00000006)

app/src/mouse/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11

2-
target_sources(app PRIVATE input_listener.c)
2+
target_sources_ifdef(CONFIG_ZMK_INPUT_LISTENER app PRIVATE input_listener.c)
33
target_sources_ifdef(CONFIG_ZMK_INPUT_PROCESSOR_TRANSFORM app PRIVATE input_processor_transform.c)
44
target_sources_ifdef(CONFIG_ZMK_INPUT_PROCESSOR_SCALER app PRIVATE input_processor_scaler.c)
55
target_sources_ifdef(CONFIG_ZMK_INPUT_PROCESSOR_TEMP_LAYER app PRIVATE input_processor_temp_layer.c)
66
target_sources_ifdef(CONFIG_ZMK_INPUT_PROCESSOR_CODE_MAPPER app PRIVATE input_processor_code_mapper.c)
7-
target_sources_ifdef(CONFIG_ZMK_MOUSE_SMOOTH_SCROLLING app PRIVATE resolution_multipliers.c)
7+
target_sources_ifdef(CONFIG_ZMK_MOUSE_SMOOTH_SCROLLING app PRIVATE resolution_multipliers.c)
8+
target_sources_ifdef(CONFIG_ZMK_INPUT_SPLIT app PRIVATE input_split.c)

app/src/mouse/Kconfig

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,29 @@ if ZMK_MOUSE
1212
config INPUT_GPIO_KEYS
1313
default n
1414

15+
config INPUT_THREAD_STACK_SIZE
16+
default 1024 if ZMK_SPLIT && !ZMK_SPLIT_ROLE_CENTRAL
17+
18+
if !ZMK_SPLIT || ZMK_SPLIT_ROLE_CENTRAL
19+
1520
config ZMK_MOUSE_SMOOTH_SCROLLING
1621
bool "Smooth Scrolling"
1722
help
1823
Enable smooth scrolling, with hosts that support HID Resolution Multipliers
1924

25+
config ZMK_INPUT_LISTENER
26+
bool "Input listener for processing input events in the system"
27+
default y
28+
depends on DT_HAS_ZMK_INPUT_LISTENER_ENABLED
29+
30+
31+
config ZMK_INPUT_PROCESSOR_TEMP_LAYER
32+
bool "Temporary Layer Input Processor"
33+
default y
34+
depends on DT_HAS_ZMK_INPUT_PROCESSOR_TEMP_LAYER_ENABLED
35+
36+
endif
37+
2038
config ZMK_INPUT_PROCESSOR_TRANSFORM
2139
bool "Transform Input Processor"
2240
default y
@@ -27,15 +45,14 @@ config ZMK_INPUT_PROCESSOR_SCALER
2745
default y
2846
depends on DT_HAS_ZMK_INPUT_PROCESSOR_SCALER_ENABLED
2947

30-
config ZMK_INPUT_PROCESSOR_TEMP_LAYER
31-
bool "Temporary Layer Input Processor"
32-
default y
33-
depends on DT_HAS_ZMK_INPUT_PROCESSOR_TEMP_LAYER_ENABLED
34-
3548
config ZMK_INPUT_PROCESSOR_CODE_MAPPER
3649
bool "Code Mapper Input Processor"
3750
default y
3851
depends on DT_HAS_ZMK_INPUT_PROCESSOR_CODE_MAPPER_ENABLED
3952

53+
config ZMK_INPUT_SPLIT
54+
bool "Split input support"
55+
default y
56+
depends on DT_HAS_ZMK_INPUT_SPLIT_ENABLED && ZMK_SPLIT
4057

4158
endif

app/src/mouse/input_split.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2024 The ZMK Contributors
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
7+
#define DT_DRV_COMPAT zmk_input_split
8+
9+
#include <zephyr/kernel.h>
10+
#include <zephyr/device.h>
11+
#include <zephyr/input/input.h>
12+
#include <drivers/input_processor.h>
13+
14+
#include <zephyr/logging/log.h>
15+
16+
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
17+
18+
#if IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
19+
20+
struct zis_entry {
21+
uint8_t reg;
22+
const struct device *dev;
23+
};
24+
25+
#define ZIS_ENTRY(n) {.reg = DT_INST_REG_ADDR(n), .dev = DEVICE_DT_GET(DT_DRV_INST(n))},
26+
27+
static const struct zis_entry proxy_inputs[] = {DT_INST_FOREACH_STATUS_OKAY(ZIS_ENTRY)};
28+
29+
int zmk_input_split_report_peripheral_event(uint8_t reg, uint8_t type, uint16_t code, int32_t value,
30+
bool sync) {
31+
LOG_DBG("Got peripheral event for %d!", reg);
32+
for (size_t i = 0; i < ARRAY_SIZE(proxy_inputs); i++) {
33+
if (reg == proxy_inputs[i].reg) {
34+
return input_report(proxy_inputs[i].dev, type, code, value, sync, K_NO_WAIT);
35+
}
36+
}
37+
38+
return -ENODEV;
39+
}
40+
41+
#define ZIS_INST(n) \
42+
DEVICE_DT_INST_DEFINE(n, NULL, NULL, NULL, NULL, POST_KERNEL, \
43+
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL);
44+
45+
DT_INST_FOREACH_STATUS_OKAY(ZIS_INST)
46+
47+
#else
48+
49+
#include <zmk/split/bluetooth/service.h>
50+
51+
#define ZIS_INST(n) \
52+
static const struct zmk_input_processor_entry processors_##n[] = \
53+
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, input_processors), \
54+
({LISTIFY(DT_INST_PROP_LEN(n, input_processors), \
55+
ZMK_INPUT_PROCESSOR_ENTRY_AT_IDX, (, ), DT_DRV_INST(n))}), \
56+
({})); \
57+
BUILD_ASSERT(DT_INST_NODE_HAS_PROP(n, device), \
58+
"Peripheral input splits need an `input` property set"); \
59+
void split_input_handler_##n(struct input_event *evt) { \
60+
for (size_t i = 0; i < ARRAY_SIZE(processors_##n); i++) { \
61+
zmk_input_processor_handle_event(processors_##n[i].dev, evt, processors_##n[i].param1, \
62+
processors_##n[i].param2, NULL); \
63+
} \
64+
zmk_split_bt_report_input(DT_INST_REG_ADDR(n), evt->type, evt->code, evt->value, \
65+
evt->sync); \
66+
} \
67+
INPUT_CALLBACK_DEFINE(DEVICE_DT_GET(DT_INST_PHANDLE(n, device)), split_input_handler_##n);
68+
69+
DT_INST_FOREACH_STATUS_OKAY(ZIS_INST)
70+
71+
#endif

0 commit comments

Comments
 (0)