blob: a4603b5ff1dd3a1c85e36dd9abc14165a83763e5 [file] [view]
# Zephyr EC Keyboard Configuration
[TOC]
## Overview
This provides an overview of the Keyboard configuration and options.
## Reference implementations
A full configuration of a keyboard device on NPCX is available in
[keyboard-rex] and on ITE on [keyboard-brox]. For a reference using a full 18x8
matrix see [keyboard-jubilant].
## Kconfig Options
Kconfig Option | Default | Documentation
:------------- | :------ | :------------
`CONFIG_INPUT` | n | Enables the input subsystem, required by the keyboard driver
`CONFIG_PM_DEVICE_RUNTIME` | n | Enables the runtime PM APIs, required by the keyboard driver to work properly
`CONFIG_CROS_EC_KEYBOARD_INPUT` | n | Enable the input subsystem based keyboard driver
`CONFIG_INPUT_SHELL` | n | General option to enable the input shell commands
`CONFIG_INPUT_SHELL_KBD_MATRIX_STATE` | n | Enable the keyboard matrix debug shell command
## Devicetree Nodes
The keyboard device is configured by extending the `kbd` node for a specific
program, typically in a dedicated `keyboard.dtsi` file. A basic configuration
should contain the list of pins and matrix size in row and columns.
```
&kbd {
status = "okay";
pinctrl-0 = <
&ksi0_default
...
&kso12_default
>;
pinctrl-1 = <
&ksi0_sleep
...
&kso12_sleep
>;
pinctrl-names = "default", "sleep";
row-size = <8>;
col-size = <13>;
};
```
Few extra properties are available to fine tune the keyboard scanning algorithm
Property | Description | Settings
:------- | :---------- | :-------
`poll-period-ms` | Defines the poll period in milliseconds between between matrix scans. | `int` (default 5)
`poll-timeout-ms` | How long to wait before going from polling back to idle state. | `int` (default 100)
`debounce-down-ms` | Debouncing time for a key press event. | `int` (default 10)
`debounce-up-ms` | Debouncing time for a key release event. | `int` (default 20)
`settle-time-us` | Delay between setting column output and reading the row values. | `int` (default 50)
`actual-key-mask` | Keyboard scanning mask. For each keyboard column, specify which keyboard rows actually exist. | `array of uint8` (default unset)
`no-ghostkey-check` | Ignore the ghost key checking in the driver, for devices with anti ghosting diodes. | `boolean` (default n)
Typically `settle-time-us` is set to 80us to account for signal propagation
delay in the col2 data line.
Other features are configured using devicetree nodes, defined as child nodes of
the keyboard device:
### KSO2
The KSO2 signal typically has its own dedicated handling code, the pin is
defined with a special `cros-ec,col-gpio` node, for example:
```
&kbd {
...
kso-gpio {
compatible = "cros-ec,col-gpio";
col-num = <2>;
col-gpios = <&gpioksol 2 GPIO_ACTIVE_HIGH>;
};
...
};
```
The `col-num` property specifies which column to handle, and `col-gpios` what
GPIO to use.
### Boot and runtime keys
The boot and runtime key row and column keys are configured with a
`cros-ec,boot-keys` node, for example:
```
&kbd {
...
boot-keys {
compatible = "cros-ec,boot-keys";
down-arrow-rc = <KBD_RC(6, 11)>;
esc-rc = <KBD_RC(1, 1)>;
left-shift-rc = <KBD_RC(5, 7)>;
refresh-rc = <KBD_RC(3, 2)>;
};
runtime-keys {
compatible = "cros-ec,runtime-keys";
left-alt-rc = <KBD_RC(0, 10)>;
right-alt-rc = <KBD_RC(6, 10)>;
h-rc = <KBD_RC(1, 6)>;
r-rc = <KBD_RC(7, 3)>;
};
...
};
```
Note that runtime-keys operation requires a Vivaldi keyboard configuration node
as well.
### Factory test
The factory test debugging command needs its own configuration, specifying
which GPIOs are connected to each specific pin in the keyboard connector, refer
to the device schematics and define a node like:
```
&kbd {
...
factory-test {
compatible = "cros-ec,keyboard-factory-test";
pin1-gpios = <&gpioksoh 4 GPIO_ACTIVE_HIGH>;
pin2-gpios = <&gpioksoh 0 GPIO_ACTIVE_HIGH>;
...
pin24-gpios = <&gpioksi 1 GPIO_ACTIVE_HIGH>;
/* 25 nc */
pin26-gpios = <&gpioksoh 5 GPIO_ACTIVE_HIGH>;
/* 27 nc */
pin28-gpios = <&gpioksoh 6 GPIO_ACTIVE_HIGH>;
};
...
};
```
Only the pins that are actually connected need to be referenced.
### Vivaldi configuration
The Vivaldi configuration can be tweaked in the device tree in two different
ways: if there's only configuration required, just extend the default
`kbd_config_0` node directly, for example:
```
&kbd_config_0 {
vivaldi-codes = <
VIVALDI_TK_BACK /* T1 */
...
VIVALDI_TK_VOL_UP /* T10 */
>;
capabilities = <0>; /* No lock button */
};
```
If multiple configurations are used or if the key map has to be changed as
well, extend the `vivaldi_kbd` instead, for example:
```
&vivaldi_kbd {
vivaldi-keys = <
KBD_RC(0, 2) /* T1 */
...
KBD_RC(0, 11) /* T14 */
>;
kbd_config_0: kbd-config-0 {
vivaldi-codes = <
VIVALDI_TK_BACK /* T1 */
VIVALDI_TK_REFRESH /* T2 */
VIVALDI_TK_FULLSCREEN /* T3 */
VIVALDI_TK_OVERVIEW /* T4 */
VIVALDI_TK_SNAPSHOT /* T5 */
VIVALDI_TK_BRIGHTNESS_DOWN /* T6 */
VIVALDI_TK_BRIGHTNESS_UP /* T7 */
VIVALDI_TK_KBD_BKLIGHT_TOGGLE /* T8 */
VIVALDI_TK_DICTATE /* T9 */
VIVALDI_TK_ACCESSIBILITY /* T10 */
VIVALDI_TK_MICMUTE /* T11 */
VIVALDI_TK_VOL_MUTE /* T12 */
VIVALDI_TK_VOL_DOWN /* T13 */
VIVALDI_TK_VOL_UP /* T14 */
>;
capabilities = < (VIVALDI_KEYBD_CAP_FUNCTION_KEYS |
VIVALDI_KEYBD_CAP_NUMERIC_KEYPAD |
VIVALDI_KEYBD_CAP_SCRNLOCK_KEY |
VIVALDI_KEYBD_CAP_ASSISTANT_KEY) >;
};
kbd_config_1: kbd-config-1 {
vivaldi-codes = <
VIVALDI_TK_BACK /* T1 */
VIVALDI_TK_REFRESH /* T2 */
VIVALDI_TK_FULLSCREEN /* T3 */
VIVALDI_TK_OVERVIEW /* T4 */
VIVALDI_TK_SNAPSHOT /* T5 */
VIVALDI_TK_BRIGHTNESS_DOWN /* T6 */
VIVALDI_TK_BRIGHTNESS_UP /* T7 */
VIVALDI_TK_DICTATE /* T8 */
VIVALDI_TK_ACCESSIBILITY /* T9 */
VIVALDI_TK_PLAY_PAUSE /* T10 */
VIVALDI_TK_MICMUTE /* T11 */
VIVALDI_TK_VOL_MUTE /* T12 */
VIVALDI_TK_VOL_DOWN /* T13 */
VIVALDI_TK_VOL_UP /* T14 */
>;
capabilities = < (VIVALDI_KEYBD_CAP_FUNCTION_KEYS |
VIVALDI_KEYBD_CAP_NUMERIC_KEYPAD |
VIVALDI_KEYBD_CAP_SCRNLOCK_KEY |
VIVALDI_KEYBD_CAP_ASSISTANT_KEY) >;
};
};
```
The effective configuration can then be enabled in the board code by
implementing a `board_vivaldi_keybd_idx` function and referring to the child
node index, for example:
```
#include <drivers/vivaldi_kbd.h>
static bool key_bl = FW_KB_BL_NOT_PRESENT;
int8_t board_vivaldi_keybd_idx(void)
{
if (key_bl == FW_KB_BL_NOT_PRESENT) {
return VIVALDI_CFG_IDX(kbd_config_1));
} else {
return VIVALDI_CFG_IDX(kbd_config_0));
}
}
```
### Fn keys
The keyboard driver can generate an alternate key code for selected keys when a
function (Fn) key is also pressed, this is configured using a `cros-ec,fn-keys`
node.
```
#include <zephyr/dt-bindings/input/keymap.h>
kbd {
fn-keys {
compatible = "cros-ec,fn-keys";
fn-rc = <KBD_RC(2, 0)>;
keymap = <
MATRIX_KEY(1, 1, KBD_SCANCODE_F1)
MATRIX_KEY(0, 2, KBD_SCANCODE_F2)
...
MATRIX_KEY(0, 4, KBD_SCANCODE_F11)
MATRIX_KEY(3, 9, KBD_SCANCODE_F12)
>;
};
};
```
The scancode is the set2 version, which is going to then get translated by the
8042 driver according to the [8042 protocol], and then mapped to Linux input
key events according to the map defined in [Coreboot ACPI tables].
## Testing and Debugging
### Shell Command
Command | Description | Usage
:------ | :---------- | :----
`ksstate` | Print the keyboard scanning mask state | `ksstate`
`kbpress` | Inject a fake press or release event | `kbpress <row> <col> <1 or 0>`
`kbfactorytest` | Scans the keyboard matrix pins and reports any detected short circuit | `kbfactorytest`
`input dump` | Enables printing of any input event (needs `CONFIG_INPUT_SHELL=y` and `CONFIG_INPUT_EVENT_DUMP=y` | `input dump <on or off>`
`input kbd_matrix_state_dump` | Enables printing of the keyboard matrix state and reports a keymask when deactivated | `input kbd_matrix_state_dump <device or off>`
[keyboard-rex]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/program/rex/keyboard.dtsi
[keyboard-brox]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/program/brox/keyboard.dtsi
[keyboard-jubilant]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/program/brox/jubilant/keyboard.dtsi
[8042 protocol]: https://www.scs.stanford.edu/10wi-cs140/pintos/specs/kbd/scancodes-9.html
[Coreboot ACPI tables]: https://github.com/coreboot/coreboot/blob/main/src/acpi/acpigen_ps2_keybd.c