1.. _gpio-kbd:
2
3GPIO Keyboard Matrix
4####################
5
6The :dtcompatible:`gpio-kbd-matrix` driver supports a large variety of keyboard
7matrix hardware configurations and has numerous options to change its behavior.
8This is an overview of some common setups and how they can be supported by the
9driver.
10
11The conventional configuration for all of these is that the driver reads on the
12row GPIOs (inputs) and selects on the columns GPIOs (output).
13
14Base use case, no isolation diodes, interrupt capable GPIOs
15***********************************************************
16
17This is the common configuration found on consumer keyboards with membrane
18switches and flexible circuit boards, no isolation diodes, requires ghosting
19detection (which is enabled by default).
20
21.. figure:: no-diodes.svg
22      :align: center
23      :width: 50%
24
25      A 3x3 matrix, no diodes
26
27The system must support GPIO interrupts, and the interrupt can be enabled on all
28row GPIOs at the same time.
29
30.. code-block:: devicetree
31
32   kbd-matrix {
33        compatible = "gpio-kbd-matrix";
34        row-gpios = <&gpio0 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
35                    <&gpio0 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
36                    <&gpio0 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
37        col-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>,
38                    <&gpio0 4 GPIO_ACTIVE_LOW>,
39                    <&gpio0 5 GPIO_ACTIVE_LOW>;
40   };
41
42In this configuration the matrix scanning library enters idle mode once all
43keys are released, and the keyboard matrix thread only wakes up when a key has
44been pressed.
45
46GPIOs for columns that are not currently selected are configured in high
47impedance mode. This means that the row state may need some time to settle to
48avoid misreading the key state from a column to the following one. The settle
49time can be tweaked by changing the ``settle-time-us`` property.
50
51Isolation diodes
52****************
53
54If the matrix has isolation diodes for every key, then it's possible to:
55
56 - disable ghosting detection, allowing any key combination to be detected
57 - configuring the driver to drive unselected columns GPIO to inactive state
58   rather than high impedance, this allows to reduce the settle time
59   (potentially down to 0), and use the more efficient port wide GPIO read APIs
60   (happens automatically if the GPIO pins are sequential)
61
62Matrixes with diodes going from rows to columns must use pull-ups on rows and
63active low columns.
64
65.. figure:: diodes-rc.svg
66      :align: center
67      :width: 50%
68
69      A 3x3 matrix with row to column isolation diodes.
70
71.. code-block:: devicetree
72
73   kbd-matrix {
74        compatible = "gpio-kbd-matrix";
75        row-gpios = <&gpio0 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
76                    <&gpio0 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
77                    <&gpio0 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
78        col-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>,
79                    <&gpio0 4 GPIO_ACTIVE_LOW>,
80                    <&gpio0 5 GPIO_ACTIVE_LOW>;
81        col-drive-inactive;
82        settle-time-us = <0>;
83        no-ghostkey-check;
84   };
85
86Matrixes with diodes going from columns to rows must use pull-downs on rows and
87active high columns.
88
89.. figure:: diodes-cr.svg
90      :align: center
91      :width: 50%
92
93      A 3x3 matrix with column to row isolation diodes.
94
95.. code-block:: devicetree
96
97   kbd-matrix {
98        compatible = "gpio-kbd-matrix";
99        row-gpios = <&gpio0 0 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>,
100                    <&gpio0 1 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>,
101                    <&gpio0 2 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>;
102        col-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>,
103                    <&gpio0 4 GPIO_ACTIVE_HIGH>,
104                    <&gpio0 5 GPIO_ACTIVE_HIGH>;
105        col-drive-inactive;
106        settle-time-us = <0>;
107        no-ghostkey-check;
108   };
109
110GPIO with no interrupt support
111******************************
112
113Some GPIO controllers have limitations on GPIO interrupts, and may not support
114enabling interrupts on all row GPIOs at the same time.
115
116In this case, the driver can be configured to not use interrupt at all, and
117instead idle by selecting all columns and keep polling on the row GPIOs, which
118is a single GPIO API operation if the pins are sequential.
119
120This configuration can be enabled by setting the ``idle-mode`` property to
121``poll``:
122
123.. code-block:: devicetree
124
125   kbd-matrix {
126        compatible = "gpio-kbd-matrix";
127        ...
128        idle-mode = "poll";
129   };
130
131GPIO multiplexer
132****************
133
134In more extreme cases, such as if the columns are using a multiplexer and it's
135impossible to select all of them at the same time, the driver can be configured
136to scan continuously.
137
138This can be done by setting ``idle-mode`` to ``scan`` and ``poll-timeout-ms``
139to ``0``.
140
141.. code-block:: devicetree
142
143   kbd-matrix {
144        compatible = "gpio-kbd-matrix";
145        ...
146        poll-timeout-ms = <0>;
147        idle-mode = "scan";
148   };
149
150Row and column GPIO selection
151*****************************
152
153If the row GPIOs are sequential and on the same gpio controller, the driver
154automatically switches API to read from the whole GPIO port rather than the
155individual pins. This is particularly useful if the GPIOs are not memory
156mapped, for example on an I2C or SPI port expander, as this significantly
157reduces the number of transactions on the corresponding bus.
158
159The same is true for column GPIOs, but only if the matrix is configured for
160``col-drive-inactive``, so that is only usable for matrixes with isolation
161diodes.
162
16316-bit row support
164******************
165
166The driver uses an 8-bit datatype to store the row state by default, which
167limits the matrix row size to 8. This can be increased to 16 by enabling the
168:kconfig:option:`CONFIG_INPUT_KBD_MATRIX_16_BIT_ROW` option.
169
170Actual key mask configuration
171*****************************
172
173If the key matrix is not complete, a map of the keys that are actually
174populated can be specified using the `actual-key-mask` property. This allows
175the matrix state to be filtered to remove keys that are not present before
176ghosting detection, potentially allowing key combinations that would otherwise
177be blocked by it.
178
179For example for a 3x3 matrix missing a key:
180
181.. figure:: no-sw4.svg
182      :align: center
183      :width: 50%
184
185      A 3x3 matrix missing a key.
186
187.. code-block:: devicetree
188
189   kbd-matrix {
190        compatible = "gpio-kbd-matrix";
191        ...
192        actual-key-mask = <0x07 0x05 0x07>;
193   };
194
195This would allow, for example, to detect pressing ``Sw1``, ``SW2`` and  ``SW4``
196at the same time without triggering anti ghosting.
197
198The actual key mask can be changed at runtime by enabling
199:kconfig:option:`CONFIG_INPUT_KBD_ACTUAL_KEY_MASK_DYNAMIC` and the using the
200:c:func:`input_kbd_matrix_actual_key_mask_set` API.
201
202Keymap configuration
203********************
204
205Keyboard matrix devices report a series of x/y/touch events. These can be
206mapped to normal key events using the :dtcompatible:`input-keymap` driver.
207
208For example, the following would setup a ``keymap`` device that take the
209x/y/touch events as an input and generate corresponding key events as an
210output:
211
212.. code-block:: devicetree
213
214  kbd {
215      ...
216      keymap {
217          compatible = "input-keymap";
218          keymap = <
219              MATRIX_KEY(0, 0, INPUT_KEY_1)
220              MATRIX_KEY(0, 1, INPUT_KEY_2)
221              MATRIX_KEY(0, 2, INPUT_KEY_3)
222              MATRIX_KEY(1, 0, INPUT_KEY_4)
223              MATRIX_KEY(1, 1, INPUT_KEY_5)
224              MATRIX_KEY(1, 2, INPUT_KEY_6)
225              MATRIX_KEY(2, 0, INPUT_KEY_7)
226              MATRIX_KEY(2, 1, INPUT_KEY_8)
227              MATRIX_KEY(2, 2, INPUT_KEY_9)
228          >;
229          row-size = <3>;
230          col-size = <3>;
231      };
232  };
233
234Keyboard matrix shell commands
235******************************
236
237The shell command ``kbd_matrix_state_dump`` can be used to test the
238functionality of any keyboard matrix driver implemented using the keyboard
239matrix library. Once enabled it logs the state of the matrix every time it
240changes, and once disabled it prints an or-mask of any key that has been
241detected, which can be used to set the ``actual-key-mask`` property.
242
243The command can be enabled using the
244:kconfig:option:`CONFIG_INPUT_SHELL_KBD_MATRIX_STATE`.
245
246Example usage:
247
248.. code-block:: console
249
250   uart:~$ device list
251   devices:
252   - kbd-matrix (READY)
253   uart:~$ input kbd_matrix_state_dump kbd-matrix
254   Keyboard state logging enabled for kbd-matrix
255   [00:01:41.678,466] <inf> input: kbd-matrix state [01 -- -- --] (1)
256   [00:01:41.784,912] <inf> input: kbd-matrix state [-- -- -- --] (0)
257   ...
258   press more buttons
259   ...
260   uart:~$ input kbd_matrix_state_dump off
261   Keyboard state logging disabled
262   [00:01:47.967,651] <inf> input: kbd-matrix key-mask [07 05 07 --] (8)
263
264Keyboard matrix library
265***********************
266
267The GPIO keyboard matrix driver is based on a generic keyboard matrix library,
268which implements the core functionalities such as scanning delays, debouncing,
269idle mode etc. This can be reused to implement other keyboard matrix drivers,
270potentially application specific.
271
272.. doxygengroup:: input_kbd_matrix
273