Skip to content

Commit 3377ed0

Browse files
authored
docs: Improve pointing docs (#2703)
docs: Add missing code fence languages in pointing docs: Fix default msc exponent in example docs: Make pointing hardware integration follow semantic structure
1 parent 36508c2 commit 3377ed0

File tree

5 files changed

+224
-63
lines changed

5 files changed

+224
-63
lines changed

docs/docs/config/pointing.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Additional properties can be set on child nodes, which allows changing the setti
5353

5454
## Input Split
5555

56-
Input splits are used for [pointing devices on split peripherals](../development/hardware-integration/pointing.mdx#split).
56+
Input splits are used for [pointing devices on split peripherals](../development/hardware-integration/pointing.mdx#listener-and-input-split-device).
5757

5858
### Devicetree
5959

Original file line numberDiff line numberDiff line change
@@ -1,28 +1,60 @@
11
---
22
title: Pointing Devices
3+
toc_max_heading_level: 2
34
---
45

56
import Tabs from "@theme/Tabs";
67
import TabItem from "@theme/TabItem";
78

8-
ZMK's pointing device support builds upon the Zephyr [input API](https://docs.zephyrproject.org/3.5.0/services/input/index.html) to offer pointing/mouse functionality with various hardware. A limited number of input drivers are available in the Zephyr version currently used by ZMK, but additional drivers can be found in [external modules](../../features/modules.mdx) for a variety of hardware.
9+
ZMK's pointing device support builds upon the Zephyr [input API](https://docs.zephyrproject.org/3.5.0/services/input/index.html) to offer pointing/mouse functionality with various hardware.
10+
A limited number of input drivers are available in the Zephyr version currently used by ZMK, but additional drivers can be found in [external modules](../../features/modules.mdx) for a variety of hardware.
911

10-
The details will depend on if you are adding a pointing device to a [split peripheral](../../features/split-keyboards.md#central-and-peripheral-roles) as opposed to a unibody keyboard or split central part:
12+
Pointing devices are also supported on split peripherals, with some additional configuration using the [input split device](../../config/pointing.md#input-split).
13+
The configuration details will thus vary depending on if you are adding a pointing device to a [split peripheral](../../features/split-keyboards.md#central-and-peripheral-roles) as opposed to a unibody keyboard or split central part.
1114

12-
<Tabs
13-
defaultValue="central"
14-
values={[
15-
{ label: "Unibody or Split Central", value: "central" },
16-
{ label: "Split Peripheral", value: "peripheral" },
17-
]}
18-
>
19-
<TabItem value="central">
15+
export const SplitTabs = (props) => (
16+
<Tabs
17+
groupId="part-type"
18+
defaultValue="unibody"
19+
values={[
20+
{ label: "Unibody", value: "unibody" },
21+
{ label: "Split Central", value: "central" },
22+
{ label: "Split Peripheral", value: "peripheral" },
23+
]}
24+
>
25+
26+
{/* eslint-disable-next-line */}
27+
{props.children}
28+
29+
</Tabs>
30+
31+
);
2032

2133
## Input Device
2234

23-
First, we must define the pointing device itself. The specifics of where this node goes will depend on the specific hardware. _Most_ pointing hardware uses either SPI or I2C for communication, and will be nested under a properly configured bus node, e.g. `&pro_micro_i2c` or for a complete onboard setup, `&i2c3`. See the documentation on [pin control](./pinctrl.mdx) if you need to configure the pins for an I2C or SPI bus.
35+
First, we must define the pointing device itself. The specifics of where this node goes will depend on the specific hardware.
36+
_Most_ pointing hardware uses either SPI or I2C for communication, and will be nested under a properly configured bus node, e.g. `&pro_micro_i2c` or for a complete onboard setup, `&i2c3`.
37+
See the documentation on [pin control](./pinctrl.mdx) if you need to configure the pins for an I2C or SPI bus.
2438

25-
For example, if setting up an [SPI device](https://github.com/zmkfirmware/zephyr/blob/v3.5.0%2Bzmk-fixes/dts/bindings/spi/spi-device.yaml), you may have a node like:
39+
This node should always be set up in the `.overlay`/`.dts` file for the keyboard side that has the device attached to it.
40+
41+
<SplitTabs>
42+
<TabItem value="unibody">
43+
44+
For example, if setting up an [SPI device](https://github.com/zmkfirmware/zephyr/blob/v3.5.0%2Bzmk-fixes/dts/bindings/spi/spi-device.yaml), a node like following would be added to the `.overlay`/`.dts` file for the keyboard, like `<keyboard>.overlay`:
45+
46+
</TabItem>
47+
<TabItem value="central">
48+
49+
For example, if setting up an [SPI device](https://github.com/zmkfirmware/zephyr/blob/v3.5.0%2Bzmk-fixes/dts/bindings/spi/spi-device.yaml) on a central part, a node like following would be added to the `.overlay`/`.dts` file for the central part of the keyboard, like `<central>.overlay`:
50+
51+
</TabItem>
52+
<TabItem value="peripheral">
53+
54+
For example, if setting up an [SPI device](https://github.com/zmkfirmware/zephyr/blob/v3.5.0%2Bzmk-fixes/dts/bindings/spi/spi-device.yaml) on one of the peripheral parts, a node like following would be added to the `.overlay`/`.dts` file for that peripheral part, like `<peripheral>.overlay`:
55+
56+
</TabItem>
57+
</SplitTabs>
2658

2759
```dts
2860
&pro_micro_spi {
@@ -45,11 +77,19 @@ For example, if setting up an [SPI device](https://github.com/zmkfirmware/zephyr
4577

4678
The specifics of the properties required to set for a given driver will vary; always consult the devicetree bindings file for the specific driver to see what properties can be set.
4779

48-
## Listener
80+
## Listener and Input Split Device
4981

50-
Every input device needs an associated listener added that listens for events from the device and processes them before sending the events to the host using a HID mouse report. See [input listener configuration](../../config/pointing.md#input-listener) for the full details. For example, to add a listener for the above device:
82+
Every input device needs an associated listener added that listens for events from the device and processes them before sending the events to the host using a HID mouse report.
83+
See [input listener configuration](../../config/pointing.md#input-listener) for the full details.
5184

52-
```dts
85+
If your pointing device is on a split peripheral part, you also need to define and use an input split device on all keyboard parts.
86+
87+
<SplitTabs>
88+
<TabItem value="unibody">
89+
90+
To add a listener for the above device, add to your `.overlay`/`.dts` file for the keyboard a node like the following:
91+
92+
```dts title="<keyboard>.overlay"
5393
/ {
5494
glidepoint_listener {
5595
compatible = "zmk,input-listener";
@@ -58,40 +98,81 @@ Every input device needs an associated listener added that listens for events fr
5898
};
5999
```
60100

61-
## Input Processors
101+
</TabItem>
102+
<TabItem value="central">
62103

63-
Some physical pointing devices may be generating input events that need adjustment before being sent to hosts. For example a trackpad might be integrated into a keyboard rotated 90° and need the X/Y data adjusted appropriately. This can be accomplished with [input processors](../../keymaps/input-processors/index.md). As an example, you could enhance the above listener with the following input processor that inverts and swaps the X/Y axes:
104+
### Shared Configuration
64105

65-
```dts
66-
#include <dt-bindings/zmk/input_transform.h>
106+
The input listener that is used by the central side is added to the shared `.dtsi` file that is included into both central and peripheral `.overlay`/`.dts` files.
107+
108+
The input listener is disabled by default, and will be enabled later in the central part's overlay. This is so that keymaps (which are included for both central and peripheral builds) can reference the listener to add input processors without failing with an undefined reference error.
67109

110+
```dts title="<keyboard>.dtsi"
68111
/ {
69-
glidepoint_listener {
112+
glidepoint_listener: glidepoint_listener {
70113
compatible = "zmk,input-listener";
71-
device = <&glidepoint>;
72-
input-processors = <&zip_xy_transform (INPUT_TRANSFORM_XY_SWAP | INPUT_TRANSFORM_X_INVERT | INPUT_TRANSFORM_Y_INVERT)>;
114+
status = "disabled";
73115
};
74116
};
117+
```
118+
119+
If users want to add [input processors](#input-processors) to the listener node, they will use the corresponding node reference (here it is `&glidepoint_listener`) in their keymaps.
120+
121+
### Central Configuration
122+
123+
In the central, we do the following:
124+
125+
- Include the shared .dtsi file.
126+
- Enable the input listener that is created in our shared file.
127+
- Assign the pointing device node to the listener.
128+
129+
```dts title="<central>.overlay"
130+
// Pull in the shared configuration
131+
#include "<keyboard>.dtsi"
132+
133+
// Node from the previous Input Device section
134+
&pro_micro_spi {
135+
/* ... */
136+
137+
glidepoint: glidepoint@0 {
138+
/* ... */
139+
};
140+
};
141+
142+
// Overrides for the input listener node
143+
&glidepoint_listener {
144+
status = "okay";
145+
device = <&glidepoint>;
146+
};
147+
```
148+
149+
### Peripheral Configuration
150+
151+
Finally, we include the shared file in all peripherals so that the listener node reference is available like mentioned above:
152+
153+
```dts title="<peripheral>.overlay"
154+
#include "<keyboard>.dtsi"
75155
```
76156

77157
</TabItem>
78158
<TabItem value="peripheral">
79159

80-
## Split
160+
### Shared Configuration
81161

82-
Pointing devices are supported on split peripherals, with some additional configuration using the [input split device](../../config/pointing.md#input-split). All split pointers are identified using a unique integer value, which is specified using the `reg` property and in the `@#` suffix for the node. If adding multiple peripheral pointers, be sure that each is given a unique identifier.
162+
When a pointing device is on a peripheral, both peripheral and central make use of a `zmk,input-split` device, which functions differently depending on where it is used.
163+
To avoid duplicating work, this node can be defined in the shared `.dtsi` file that is included into both central and peripheral `.overlay`/`.dts` files.
83164

84-
### Shared
165+
All split pointers are identified using a unique integer value, which is specified using the `reg` property and in the `@#` suffix for the node. If adding multiple peripheral pointers, be sure that each is given a unique identifier.
85166

86-
Both peripheral and central make use of a `zmk,input-split` device, which functions differently depending on where it is used. To avoid duplicating work, this node can be defined in a common `.dtsi` file that is included into both central and peripheral `.overlay`/`.dts` files. Second, the input listener for the central side is added here, but disabled, so that keymaps (which are included for central and peripheral builds) can reference the listener to add input processors without issue.
167+
Second, the input listener that is used by the central side is added here but disabled by default. This is so that keymaps (which are included for both central and peripheral builds) can reference the listener to add input processors without failing with an undefined reference error.
87168

88169
:::note
89170

90171
Input splits need to be nested under a parent node that properly sets `#address-cells = <1>` and `#size-cells = <0>`. These settings are what allow us to use a single integer number for the `reg` value.
91172

92173
:::
93174

94-
```dts
175+
```dts title="<keyboard>.dtsi"
95176
/ {
96177
split_inputs {
97178
#address-cells = <1>;
@@ -111,58 +192,138 @@ Input splits need to be nested under a parent node that properly sets `#address-
111192
};
112193
```
113194

114-
### Peripheral
195+
If users want to add [input processors](#input-processors) to the listener node, they will use the corresponding node reference (here it is `&glidepoint_listener`) in their keymaps.
196+
197+
### Peripheral Configuration
115198

116199
In the peripheral .overlay/.dts file, we do the following:
117200

118201
- Include the shared .dtsi file.
119-
- Add the device node for the physical pointer.
120202
- Update the input split with a reference to the new device node that should be proxied.
121203

122-
```dts
123-
#include "common.dtsi"
204+
```dts title="<peripheral>.overlay"
205+
// Pull in the shared configuration
206+
#include "<keyboard>.dtsi"
124207
208+
// Node from the previous Input Device section
125209
&pro_micro_spi {
126-
status = "okay";
127-
cs-gpios = <&pro_micro 19 GPIO_ACTIVE_LOW>;
210+
/* ... */
128211
129212
glidepoint: glidepoint@0 {
130-
compatible = "cirque,pinnacle";
131-
reg = <0>;
132-
spi-max-frequency = <1000000>;
133-
status = "okay";
134-
dr-gpios = <&pro_micro 5 (GPIO_ACTIVE_HIGH)>;
135-
136-
sensitivity = "4x";
137-
sleep;
138-
no-taps;
213+
/* ... */
139214
};
140215
};
141216
217+
// Overrides for the input-split child node
142218
&glidepoint_split {
143219
device = <&glidepoint>;
144220
221+
// Optional
145222
input-processors = <&zip_xy_transform (INPUT_TRANSFORM_XY_SWAP | INPUT_TRANSFORM_X_INVERT | INPUT_TRANSFORM_Y_INVERT)>;
146223
};
147224
```
148225

149-
The `input-processors` property on the input split is optional, and only necessary if the input needs to be fixed up before it is sent to the central.
226+
The [`input-processors` property](#input-processors) on the input split is optional, and only necessary if the input needs to be fixed up before it is sent to the central.
150227

151-
The specifics of where the pointing device node goes will depend on the specific hardware. _Most_ pointing hardware uses either SPI or I2C for communication, and will be nested under a properly configured bus node, e.g. `&pro_micro_i2c` or for a complete onboard setup, `&i2c3`. See the documentation on [pin control](./pinctrl.mdx) if you need to configure the pins for an I2C or SPI bus.
228+
### Central Configuration
152229

153-
The specifics of the properties required to set for a given driver will vary; always consult the devicetree bindings file for the specific driver to see what properties can be set.
230+
On the central, the input split acts as an input device, receiving events from the peripheral and raising them locally.
231+
Here we first include the shared file, and then enable the input listener that is created, but disabled, in our shared file:
154232

155-
### Central
233+
```dts title="<central>.overlay"
234+
#include "<keyboard>.dtsi"
156235
157-
On the central, the input split acts as an input device, receiving events from the peripheral and raising them locally. First, include the shared file, and then enabled the [input listener](#listener) that is created, but disabled, in our shared file:
236+
&glidepoint_listener {
237+
status = "okay";
238+
};
239+
```
240+
241+
</TabItem>
242+
</SplitTabs>
243+
244+
## Input Processors
245+
246+
Some physical pointing devices may be generating input events that need adjustment before being sent to hosts.
247+
For example a trackpad might be integrated into a keyboard rotated 90° and need the X/Y data adjusted appropriately.
248+
This can be accomplished with [input processors](../../keymaps/input-processors/index.md).
249+
As an example, you could enhance the listener defined in the previous section with an input processor that inverts and swaps the X/Y axes:
158250

159251
```dts
160-
#include "common.dtsi"
252+
#include <dt-bindings/zmk/input_transform.h>
161253
162-
&glidepoint_listener {
163-
status = "okay";
254+
/ {
255+
glidepoint_listener {
256+
compatible = "zmk,input-listener";
257+
device = <&glidepoint>;
258+
input-processors = <&zip_xy_transform (INPUT_TRANSFORM_XY_SWAP | INPUT_TRANSFORM_X_INVERT | INPUT_TRANSFORM_Y_INVERT)>;
259+
};
164260
};
261+
```
262+
263+
## Configuration Setting
264+
265+
If your keyboard hardware includes a pointing device by default, you can enable the [`ZMK_POINTING` config](../../config/pointing.md#general) in your keyboard definition.
266+
You can do that in your [`Kconfig.defconfig` file](new-shield.mdx#kconfigdefconfig), where you can also enable the config for the communication protocol (e.g. [SPI](https://docs.zephyrproject.org/3.5.0/kconfig.html#CONFIG_SPI), [I2C](https://docs.zephyrproject.org/3.5.0/hardware/peripherals/i2c.html#configuration-options)) used by the pointing device:
267+
268+
<SplitTabs>
269+
<TabItem value="unibody">
270+
271+
```kconfig title="Kconfig.defconfig"
272+
if SHIELD_MY_KEYBOARD
273+
274+
# Other keyboard settings
275+
276+
config ZMK_POINTING
277+
default y
278+
279+
# Assuming pointing device uses SPI
280+
config SPI
281+
default y
282+
283+
endif
165284
```
166285

167286
</TabItem>
168-
</Tabs>
287+
<TabItem value="central">
288+
289+
```kconfig title="Kconfig.defconfig"
290+
if SHIELD_MY_KEYBOARD_<CENTRAL>
291+
292+
# Other settings
293+
294+
config ZMK_POINTING
295+
default y
296+
297+
# Assuming pointing device uses SPI
298+
config SPI
299+
default y
300+
301+
endif
302+
```
303+
304+
</TabItem>
305+
<TabItem value="peripheral">
306+
307+
```kconfig title="Kconfig.defconfig"
308+
if SHIELD_MY_KEYBOARD_<CENTRAL> || SHIELD_MY_KEYBOARD_<PERIPHERAL>
309+
310+
# Other keyboard settings
311+
312+
config ZMK_POINTING
313+
default y
314+
315+
endif
316+
317+
if SHIELD_MY_KEYBOARD_<PERIPHERAL>
318+
319+
# Assuming pointing device uses SPI
320+
config SPI
321+
default y
322+
323+
endif
324+
```
325+
326+
</TabItem>
327+
</SplitTabs>
328+
329+
If the hardware is optional, users should set `CONFIG_ZMK_POINTING=y` manually in their [user configuration file](new-shield.mdx#user-configuration-files), along with the config for the protocol.

0 commit comments

Comments
 (0)