| `CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS` | int | Global debounce time for key press in milliseconds | -1 |
| `CONFIG_ZMK_KSCAN_DEBOUNCE_RELEASE_MS` | int | Global debounce time for key release in milliseconds | -1 |
If the debounce press/release values are set to any value other than `-1`, they override the `debounce-press-ms` and `debounce-release-ms` devicetree properties for all keyboard scan drivers which support them.
| `zmk,kscan` | path | The node for the keyboard scan driver to use |
| `zmk,matrix_transform` | path | The node for the [matrix transform](#matrix-transform) to use |
## Demux Driver
Keyboard scan driver which works like a regular matrix but uses a demultiplexer to drive the rows or columns. This allows N GPIOs to drive N<sup>2</sup> rows or columns instead of just N like with a regular matrix.
| `label` | string | Unique label for the node | |
| `rows` | int | The number rows of in the composite matrix | |
| `cols` | int | The number columns of in the composite matrix | |
The `zmk,kscan-composite` node should have one child node per keyboard scan driver that should be composited. Each child node can have the following properties:
To combine them, we need to create a composite matrix with enough rows and columns to fit both sets of keys without overlapping, then set row and/or columns offsets to shift them so they do not overlap.
One possible way to do this is a 3x4 matrix where the direct GPIO keys are shifted to below the matrix keys...
| `label` | string | Unique label for the node | |
| `event-period` | int | Milliseconds between each generated event | |
| `events` | array | List of key events to simulate | |
| `rows` | int | The number rows of in the composite matrix | |
| `cols` | int | The number columns of in the composite matrix | |
| `exit-after` | bool | Exit the program after running all events | false |
The `events` array should be defined using the macros from [dt-bindings/zmk/kscan_mock.h](https://github.com/zmkfirmware/zmk/blob/main/app/include/dt-bindings/zmk/kscan_mock.h).
## Matrix Transform
Defines a mapping from keymap logical positions to physical matrix positions.
Transforms should be used any time the physical layout of a keyboard's keys does not match the layout of its electrical matrix and/or when not all positions in the matrix are used. This applies to most non-ortholinear boards.
Transforms can also be used for keyboards with multiple layouts. You can define multiple matrix transform nodes, one for each layout, and users can select which one they want from the `/chosen` node in their keymaps.
See the [new shield guide](/docs/development/new-shield/#optional-matrix-transform) for more documentation on how to define a matrix transform.
| `rows` | int | Number of rows in the transformed matrix | |
| `columns` | int | Number of columns in the transformed matrix | |
| `row-offset` | int | Adds an offset to all rows before looking them up in the transform | 0 |
| `col-offset` | int | Adds an offset to all columns before looking them up in the transform | 0 |
| `map` | array | A list of position transforms | |
The `map` array should be defined using the `RC()` macro from [dt-bindings/zmk/matrix_transform.h](https://github.com/zmkfirmware/zmk/blob/main/app/include/dt-bindings/zmk/matrix_transform.h). It should have one item per logical position in the keymap. Each item should list the physical row and column that should trigger the key in that position.
### Example Configuration
Consider a keyboard with a [duplex matrix](https://wiki.ai03.com/books/pcb-design/page/matrices-and-duplex-matrix), where the matrix has twice as many rows and half as many columns as the keyboard has keys. A matrix transform can be used to correct for this so that keymaps can match the layout of the keys, not the layout of the matrix.