Adding a matrix keypad to Verdin iMX8MM running Torizon

I’m trying to add the matrix keypad driver in my Torizon image, but I’m not sure how to make it work or if it is being loaded correctly.

I was able to build, merge and deploy the kernel module, and also its device tree overlay.

After boot, I checked loaded modules:
image

And it appears in the list, but I checked with oscilloscope if key scan is performed, and I don’t see any changes in rows/cols gpios configured. All of them are LOW.

I am using the following dts file, which I’m also doing apply/union/deploy by using torizoncore-builder tool:

// Verdin Matrix Keypad

/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>

/ {
    matrix_keypad: matrix-keypad {
		compatible = "gpio-matrix-keypad";
		debounce-delay-ms = <5>;
		col-scan-delay-us = <2>;
		
		row-gpios = <&gpio3 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)
					&gpio5 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)
					&gpio5 26 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)
					&gpio5 27 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;

		col-gpios = <&gpio1 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)
					&gpio1 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)
					&gpio1 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)
					&gpio1 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;

		linux,keymap = <0x00000041
						0x01000042
						0x02000043
						0x03000044
						0x00010045
						0x01010046
						0x02010047
						0x03010048
						0x00020061
						0x01020062
						0x02020063
						0x03020064
						0x00030065
						0x01030066
						0x02030067
						0x03030068>;						
	};
	
};
	
&iomuxc {
	// Freeing gpios used on matrix keypad (4x4)
	/*
	pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>,
		    <&pinctrl_gpio3>, <&pinctrl_gpio4>,
		    <&pinctrl_gpio7>, <&pinctrl_gpio8>,
		    <&pinctrl_gpio_hog1>, <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>,
		    <&pinctrl_pmic_tpm_ena>;
	*/
	pinctrl-0 = <&pinctrl_gpio_hog1>, <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>,
				<&pinctrl_pmic_tpm_ena>;

};

I enable pullups in all GPIO used, but when I measure every row/col they are all LOW always, while all should be HIGH. And without pressing any key, I should measure on COLs the scan col activation every scan period, right?

The source for the driver is:
http://git.toradex.com/cgit/linux-toradex.git/tree/drivers/input/keyboard/matrix_keypad.c?h=toradex_5.4-2.3.x-imx

I used this as reference for the dts file:
http://git.toradex.com/cgit/linux-toradex.git/tree/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt?h=toradex_5.4-2.3.x-imx&id=4896fb1348713344abbd9f692b393b5fdc539bf8

I tried to map some letters (a-h/A-H) to see if it works as input for the Torizon/portainer login screen I see on my display, which works fine when a usb keyboard is connected.

Maybe there is something wrong with dts file syntax and GPIOs are not being correctly configured?
Any help will be appreciate, thanks in advance.

Best regards,
Alejandro

Verdin iMX8MM V1.1A
Verdin Development Board V1.1A
TorizonCore 5.5.0+build.11.container

Greeting @apanelli,

My first impression is that you still need to assign a defined pinctrl group to this new matrix_keypad node. I don’t believe just adding the GPIOs to the row-gpios and col-gpios properties are enough to bind the pins to the driver.

For example see this device tree node for the backlight:

backlight: backlight {
		compatible = "pwm-backlight";
		brightness-levels = <0 45 63 88 119 158 203 255>;
		default-brightness-level = <4>;
		/* Verdin I2S_2_D_OUT (DSI_1_BKL_EN/DSI_1_BKL_EN_LVDS, SODIMM 46) */
		enable-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>;
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_i2s_2_d_out_dsi_1_bkl_en>;
		power-supply = <&reg_3p3v>;
		/* Verdin PWM_3_DSI/PWM_3_DSI_LVDS (SODIMM 19) */
		pwms = <&pwm1 0 6666667 PWM_POLARITY_INVERTED>;
		status = "disabled";
	};

Despite the pin being listed in enable-gpios we still need to assign the pin via pinctrl-0. I believe you need to do something similar here. Could you give this a try and see if it improves the situation.

Best Regards,
Jeremias

Hello Jeremias,

Thanks for your answer.
I’ve tried to make a configuration like you described, but it didn’t work.
This is the dt overlay with pinctrl-0 configuration:

// Verdin Matrix Keypad

/dts-v1/;
/plugin/;

#include "imx8mm.dtsi"
#include <dt-bindings/gpio/gpio.h>

/ {
	compatible = "toradex,verdin-imx8mm";
	
    matrix_keypad: matrix-keypad {
		compatible = "gpio-matrix-keypad";
		
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_gpio_matrix_keypad>;

		debounce-delay-ms = <50>;
		col-scan-delay-us = <20>;

		row-gpios = <&gpio3 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)
					&gpio5 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)
					&gpio5 26 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)
					&gpio5 27 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;

		col-gpios = <&gpio1 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)
					&gpio1 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)
					&gpio1 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)
					&gpio1 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;

		linux,keymap = <0x00000041
						0x01000042
						0x02000043
						0x03000044
						0x00010045
						0x01010046
						0x02010047
						0x03010048
						0x00020061
						0x01020062
						0x02020063
						0x03020064
						0x00030065
						0x01030066
						0x02030067
						0x03030068>;
						
		status = "okay";
	};
	
};
	
&iomuxc {
	// Freeing gpios used on matrix keypad (4x4)
	/*
	pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>,
		    <&pinctrl_gpio3>, <&pinctrl_gpio4>,
		    <&pinctrl_gpio7>, <&pinctrl_gpio8>,
		    <&pinctrl_gpio_hog1>, <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>,
		    <&pinctrl_pmic_tpm_ena>;
	*/

	pinctrl-0 = <&pinctrl_gpio_matrix_keypad>, 
				<&pinctrl_gpio_hog1>, <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>,
				<&pinctrl_pmic_tpm_ena>;

	pinctrl_gpio_matrix_keypad: gpiomatrixkeypadgrp {
		fsl,pins = <
			MX8MM_IOMUXC_NAND_CE3_B_GPIO3_IO4		0x106	/* SODIMM 206 */
			MX8MM_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5	0x106	/* SODIMM 208 */
			MX8MM_IOMUXC_UART3_RXD_GPIO5_IO26		0x106	/* SODIMM 210 */
			MX8MM_IOMUXC_UART3_TXD_GPIO5_IO27		0x106	/* SODIMM 212 */
			MX8MM_IOMUXC_GPIO1_IO00_GPIO1_IO0		0x106	/* SODIMM 216 */
			MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11		0x106	/* SODIMM 218 */
			MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8		0x106	/* SODIMM 220 */
			MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9		0x106	/* SODIMM 222 */
		>;
	};

};

I’ve added pinctrl-names and pinctrl-0 properties to the matrix_keypad node, but I didn’t find their description as required/optional property, in gpio-matrix-keypad.txt

I also added status = "okay"; in the node, but it didn’t work also.

What I’m not sure is if the values I set on different GPIO inside the node pinctrl_gpio_matrix_keypad are correct/valid. I set 0x106 in all cases, I copied from the pinctrl_gpio1, 2,... of imx8mm-verdin.dtsi, assuming they were for GPIO configuration, but I didn’t find exactly what those values means in imx8mm reference manual. Do you know which are the register I have to look to know how to set this fileds?

Finally, I also tried removing pinctrl_gpio_matrix_keypad from pinctrl-0 property, but it didn’t make any change.
What do you suggest to do?

Best regards,
Alejandro

Does the matrix_keypad driver produce any error or messages in dmesg or anywhere? Otherwise I’m not sure how I can assume what the issue here is.

I’ve added pinctrl-names and pinctrl-0 properties to the matrix_keypad node, but I didn’t find their description as required/optional property, in gpio-matrix-keypad.txt

The pinctrl-0 wouldn’t be specified in the driver documentation. This is because pinctrl-0 is a detail of the iomuxc system that the SoC uses to pinmux the pins. Even in the example I provided with the backlight node. This property isn’t specified by the pwm-backlight driver but it’s still needed.

What I’m not sure is if the values I set on different GPIO inside the node pinctrl_gpio_matrix_keypad are correct/valid. I set 0x106 in all cases, I copied from the pinctrl_gpio1, 2,... of imx8mm-verdin.dtsi, assuming they were for GPIO configuration, but I didn’t find exactly what those values means in imx8mm reference manual. Do you know which are the register I have to look to know how to set this fileds?

These “magic numbers” are documented in the reference manual for the i.MX8M SoC. These tune things like drive strength and such. You’d need to consult the reference manual to figure out what exactly 0x106 means.

Best Regards,
Jeremias