Skip to content

Commit

Permalink
feat: Add input split support.
Browse files Browse the repository at this point in the history
  • Loading branch information
petejohanson committed Dec 2, 2024
1 parent b8a79ce commit 1146744
Show file tree
Hide file tree
Showing 10 changed files with 464 additions and 63 deletions.
2 changes: 1 addition & 1 deletion app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ target_sources_ifdef(CONFIG_USB_DEVICE_STACK app PRIVATE src/events/usb_conn_sta
target_sources(app PRIVATE src/behaviors/behavior_reset.c)
target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/behaviors/behavior_ext_power.c)
target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_SOFT_OFF app PRIVATE src/behaviors/behavior_soft_off.c)
add_subdirectory_ifdef(CONFIG_ZMK_MOUSE src/mouse/)
if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
target_sources(app PRIVATE src/hid.c)
add_subdirectory_ifdef(CONFIG_ZMK_MOUSE src/mouse/)
target_sources(app PRIVATE src/behaviors/behavior_key_press.c)
target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_KEY_TOGGLE app PRIVATE src/behaviors/behavior_key_toggle.c)
target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_HOLD_TAP app PRIVATE src/behaviors/behavior_hold_tap.c)
Expand Down
15 changes: 15 additions & 0 deletions app/dts/bindings/zmk,input-split.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
include: [base.yaml]

compatible: "zmk,input-split"

description: Device to wire up an input device for split use.

properties:
reg:
required: true

device:
type: phandle

input-processors:
type: phandle-array
10 changes: 10 additions & 0 deletions app/include/zmk/mouse/input_split.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#pragma once

int zmk_input_split_report_peripheral_event(uint8_t reg, uint8_t type, uint16_t code, int32_t value,
bool sync);
9 changes: 9 additions & 0 deletions app/include/zmk/split/bluetooth/service.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,17 @@ struct zmk_split_run_behavior_payload {
char behavior_dev[ZMK_SPLIT_RUN_BEHAVIOR_DEV_LEN];
} __packed;

struct zmk_split_input_event_payload {
uint8_t type;
uint16_t code;
uint32_t value;
uint8_t sync;
} __packed;

int zmk_split_bt_position_pressed(uint8_t position);
int zmk_split_bt_position_released(uint8_t position);
int zmk_split_bt_sensor_triggered(uint8_t sensor_index,
const struct zmk_sensor_channel_data channel_data[],
size_t channel_data_size);

int zmk_split_bt_report_input(uint8_t reg, uint8_t type, uint16_t code, int32_t value, bool sync);
1 change: 1 addition & 0 deletions app/include/zmk/split/bluetooth/uuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@
#define ZMK_SPLIT_BT_CHAR_SENSOR_STATE_UUID ZMK_BT_SPLIT_UUID(0x00000003)
#define ZMK_SPLIT_BT_UPDATE_HID_INDICATORS_UUID ZMK_BT_SPLIT_UUID(0x00000004)
#define ZMK_SPLIT_BT_SELECT_PHYS_LAYOUT_UUID ZMK_BT_SPLIT_UUID(0x00000005)
#define ZMK_SPLIT_BT_INPUT_EVENT_UUID ZMK_BT_SPLIT_UUID(0x00000006)
5 changes: 3 additions & 2 deletions app/src/mouse/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Copyright (c) 2024 The ZMK Contributors
# SPDX-License-Identifier: MIT

target_sources(app PRIVATE input_listener.c)
target_sources_ifdef(CONFIG_ZMK_INPUT_LISTENER app PRIVATE input_listener.c)
target_sources_ifdef(CONFIG_ZMK_INPUT_PROCESSOR_TRANSFORM app PRIVATE input_processor_transform.c)
target_sources_ifdef(CONFIG_ZMK_INPUT_PROCESSOR_SCALER app PRIVATE input_processor_scaler.c)
target_sources_ifdef(CONFIG_ZMK_INPUT_PROCESSOR_TEMP_LAYER app PRIVATE input_processor_temp_layer.c)
target_sources_ifdef(CONFIG_ZMK_INPUT_PROCESSOR_CODE_MAPPER app PRIVATE input_processor_code_mapper.c)
target_sources_ifdef(CONFIG_ZMK_MOUSE_SMOOTH_SCROLLING app PRIVATE resolution_multipliers.c)
target_sources_ifdef(CONFIG_ZMK_MOUSE_SMOOTH_SCROLLING app PRIVATE resolution_multipliers.c)
target_sources_ifdef(CONFIG_ZMK_INPUT_SPLIT app PRIVATE input_split.c)
35 changes: 30 additions & 5 deletions app/src/mouse/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,29 @@ if ZMK_MOUSE
config INPUT_GPIO_KEYS
default n

config INPUT_THREAD_STACK_SIZE
default 1024 if ZMK_SPLIT && !ZMK_SPLIT_ROLE_CENTRAL

if !ZMK_SPLIT || ZMK_SPLIT_ROLE_CENTRAL

config ZMK_MOUSE_SMOOTH_SCROLLING
bool "Smooth Scrolling"
help
Enable smooth scrolling, with hosts that support HID Resolution Multipliers

config ZMK_INPUT_LISTENER
bool "Input listener for processing input events in the system"
default y
depends on DT_HAS_ZMK_INPUT_LISTENER_ENABLED


config ZMK_INPUT_PROCESSOR_TEMP_LAYER
bool "Temporary Layer Input Processor"
default y
depends on DT_HAS_ZMK_INPUT_PROCESSOR_TEMP_LAYER_ENABLED

endif

config ZMK_INPUT_PROCESSOR_TRANSFORM
bool "Transform Input Processor"
default y
Expand All @@ -27,15 +45,22 @@ config ZMK_INPUT_PROCESSOR_SCALER
default y
depends on DT_HAS_ZMK_INPUT_PROCESSOR_SCALER_ENABLED

config ZMK_INPUT_PROCESSOR_TEMP_LAYER
bool "Temporary Layer Input Processor"
default y
depends on DT_HAS_ZMK_INPUT_PROCESSOR_TEMP_LAYER_ENABLED

config ZMK_INPUT_PROCESSOR_CODE_MAPPER
bool "Code Mapper Input Processor"
default y
depends on DT_HAS_ZMK_INPUT_PROCESSOR_CODE_MAPPER_ENABLED

config ZMK_INPUT_SPLIT
bool "Split input support"
default y
depends on DT_HAS_ZMK_INPUT_SPLIT_ENABLED && ZMK_SPLIT

if ZMK_INPUT_SPLIT

config ZMK_INPUT_SPLIT_INIT_PRIORITY
int "Input Split initialization priority"
default INPUT_INIT_PRIORITY

endif # ZMK_INPUT_SPLIT

endif
69 changes: 69 additions & 0 deletions app/src/mouse/input_split.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#define DT_DRV_COMPAT zmk_input_split

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/input/input.h>
#include <drivers/input_processor.h>

#include <zephyr/logging/log.h>

LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);

#if IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)

struct zis_entry {
uint8_t reg;
const struct device *dev;
};

#define ZIS_ENTRY(n) {.reg = DT_INST_REG_ADDR(n), .dev = DEVICE_DT_GET(DT_DRV_INST(n))},

static const struct zis_entry proxy_inputs[] = {DT_INST_FOREACH_STATUS_OKAY(ZIS_ENTRY)};

int zmk_input_split_report_peripheral_event(uint8_t reg, uint8_t type, uint16_t code, int32_t value,
bool sync) {
LOG_DBG("Got peripheral event for %d!", reg);
for (size_t i = 0; i < ARRAY_SIZE(proxy_inputs); i++) {
if (reg == proxy_inputs[i].reg) {
return input_report(proxy_inputs[i].dev, type, code, value, sync, K_NO_WAIT);
}
}

return -ENODEV;
}

#define ZIS_INST(n) \
DEVICE_DT_INST_DEFINE(n, NULL, NULL, NULL, NULL, POST_KERNEL, \
CONFIG_ZMK_INPUT_SPLIT_INIT_PRIORITY, NULL);

#else

#include <zmk/split/bluetooth/service.h>

#define ZIS_INST(n) \
static const struct zmk_input_processor_entry processors_##n[] = \
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, input_processors), \
({LISTIFY(DT_INST_PROP_LEN(n, input_processors), \
ZMK_INPUT_PROCESSOR_ENTRY_AT_IDX, (, ), DT_DRV_INST(n))}), \
({})); \
BUILD_ASSERT(DT_INST_NODE_HAS_PROP(n, device), \
"Peripheral input splits need an `input` property set"); \
void split_input_handler_##n(struct input_event *evt) { \
for (size_t i = 0; i < ARRAY_SIZE(processors_##n); i++) { \
zmk_input_processor_handle_event(processors_##n[i].dev, evt, processors_##n[i].param1, \
processors_##n[i].param2, NULL); \
} \
zmk_split_bt_report_input(DT_INST_REG_ADDR(n), evt->type, evt->code, evt->value, \
evt->sync); \
} \
INPUT_CALLBACK_DEFINE(DEVICE_DT_GET(DT_INST_PHANDLE(n, device)), split_input_handler_##n);

#endif

DT_INST_FOREACH_STATUS_OKAY(ZIS_INST)
Loading

0 comments on commit 1146744

Please sign in to comment.