The MCA implements a keypad controller capable of decoding up to 64 key switches in a matrix keyboard of maximum 8 rows x 8 columns. The controller detects each key press and release and implements a configurable debounce filter that prevents the detection of undesirable events caused by switch bouncing. Additionally, the MCA can wake the system from low power modes (suspend to RAM and power off) from the keyboard if configured to do so.

MCA keypad

The controller buffers the events in its internal memory, making it unlikely that events are lost due to heavy system load or interrupt latency. A standard Linux input driver is provided to access the keyboard events from user space applications.

The MCA keypad requires the addition of external pull-ups in the carrier board on each I/O of the columns. The following diagram illustrates an example of the interconnection of a 4x4 matrix keypad with the MCA.

MCA keypad schematic

Kernel configuration

You can manage the MCA keypad driver support through the following kernel configuration option:

  • MCA keypad support (CONFIG_KEYBOARD_MCA)

This option is enabled as built-in on the default ConnectCore 8M Nano kernel configuration file.

Kernel driver

File Description

drivers/input/keyboard/mca-keypad.c

MCA keypad driver

Device tree bindings and customization

The MCA keypad device tree binding is documented at Documentation/devicetree/bindings/input/digi,mca-keypad.txt.

Keypad inside the MCA

ConnectCore 8M Nano device tree
mca_cc8m: mca@63 {

	...

	mca_keypad: keypad {
		compatible = "digi,mca-keypad";
		status = "disabled";
	};
};

The MCA keypad is disabled by default, since the development kit doesn’t contain a matrix keyboard.

Example device tree overlay for the MCA keypad

The BSP contains a device tree overlay called _ov_som_mca-keypad_ccimx8mn.dts with an example of a 2x2 matrix keyboard (2 rows, 2 columns).

MCA keypad device tree overlay example
	/* Configure MCA keypad controller */
	fragment@1 {
		target = <&mca_keypad>;
		__overlay__ {
			status = "okay";
			rows-io-list = <7 17>;
			cols-io-list = <8 14>;
			pwr-off-wakeup;
			debounce-ms = <10>;
			autorepeat;
			linux,keymap = <MATRIX_KEY(0, 0, KEY_UP)
					MATRIX_KEY(0, 1, KEY_DOWN)
					MATRIX_KEY(1, 0, KEY_RIGHT)
					MATRIX_KEY(1, 1, KEY_LEFT)>;
		};
	};

You can use this as a template for describing your matrix keyboard. See Device tree files and overlays for information on enabling a device tree overlay.

Using the keypad

The Linux driver registers the MCA keypad as a standard input device that generates regular key events as specified on the device tree.

Identify the input device

Search the kernel boot messages to identify the input device associated to the MCA keypad:

# dmesg | grep mca-cc8m-keypad
[2.413417] mca-keypad mca-cc8m-keypad: 2 rows, 2 cols, 10 ms debounce, pwr-off-wakeup
[2.424550] input: mca-cc8m-keypad as /sys/devices/platform/soc@0/30800000.bus/30a20000.i2c/i2c-0/0-0063/mca-cc8m-keypad/input/event1

Sample application

You can verify the events generated by the keyboard using an application such as evtest.c over the input device:

# ./evtest /dev/input/event1
Input driver version is 1.0.1
Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0
Input device name: "mca-cc8m-keypad"
Supported events:
  Event type 0 (Sync)
  Event type 1 (Key)
    Event code 103 (Up)
    Event code 105 (Left)
    Event code 106 (Right)
    Event code 108 (Down)
  Event type 4 (Misc)
    Event code 4 (ScanCode)
  Event type 20 (Repeat)
Testing ... (interrupt to exit)
Event: time 1600863381.976341, type 4 (Misc), code 4 (ScanCode), value 07
Event: time 1600863381.976341, type 1 (Key), code 115 (VolumeUp), value 1
Event: time 1600863381.976341, -------------- Report Sync ------------
Event: time 1600863382.094406, type 4 (Misc), code 4 (ScanCode), value 07
Event: time 1600863382.094406, type 1 (Key), code 115 (VolumeUp), value 0
Event: time 1600863382.094406, -------------- Report Sync ------------

Each time you press a key, two events are generated. The application represents the key scan code and its Linux code and name. The first event (with value=1) represents the pressing of the key; the second (with value=0), represents the release of the key.

Power management

Wake up from suspend-to-ram

By default, the MCA keypad is able to wake the system from suspend-to-ram state. You can manually enable or disable this functionality by writing the keywords "enabled" or "disabled" in the corresponding file in the sysfs:

# cat /sys/devices/platform/soc@0/30800000.bus/30a20000.i2c/i2c-0/0-0063/mca-cc8m-keypad/power/wakeup
enabled
# echo disabled > /sys/devices/platform/soc@0/30800000.bus/30a20000.i2c/i2c-0/0-0063/mca-cc8m-keypad/power/wakeup
# cat /sys/devices/platform/soc@0/30800000.bus/30a20000.i2c/i2c-0/0-0063/mca-cc8m-keypad/power/wakeup
disabled

Wake up from power-off

If the boolean property pwr-off-wakeup is present on the device tree, the MCA keypad can wake the system from power-off state.