I have a board with an imx8mp for which I'm tweaking the OS with Yocto (that I've started using/learning with this project). I'm working with kernel 5.10.72.
What I need
The board have a strip with some pins that I want to configure as plain input/output.
I want to:
- have the pins set up as input or output (and, for outputs, be set as high/low) as soon as possible (at start of kernel/uboot)
- be able to play with in/out from the software I'll run on the board; read the inputs status from time to time; set the outputs high/low when needed
- have the gpio already mapped/exported with a custom label in
/sys/class/gpio/
, without needing to export manually on startup, using the gpio number
How to achieve this?
What I've done so far
I've read dozen of sources, but I didn't find a good solution for all of the points above.
gpio-export
The first test I made was putting the pin in the hog group and use the gpio-export
feature. Trick mentioned in several places; here the most concise one.
This allows me to control the pins from userspace (point 2 checked), but I need to export, set direction and use gpio numbers (point 3 failed). Looks like this is due to the fact that gpio-export
is an old feature, not available on newer kernels (5.10 doesn't support it). It also partially fails point 1, since the pins will be set as output and driven when the os is up and running. I said "partially" because the not-setup pins are set as input by default, so input pins are actually correctly setup at kernel start.
A super dirty trick to have the input exported with labels for the user is to have a startup script that exports the gpios and creates a symbolic link with the desired label, so the user will find the inputs ready to be used. Super awful, but still an idea. A device tree solution is preferred.
leds
This interesting thread says that hog is mainly a bin for unused pins than something to use to map in/outs. The only mentioned (quick and dirt) solution is to use leds for outputs and gpio-keys for inputs.
I've declared the output as leds. This way all the outputs are set as soon as the kernel starts (point 1 checked), I can control them from userspace (point 2 checked) and are already mapped with custom labels (point 3 checked). The only downside is the fact that they are not mapped as gpio but as leds (obviously), and I need to play with "brightness" property to set a gpio high/low instead of the more straightforward "value" property of gpios.
Regarding the inputs, gpio-keys are more event driven, while I want to read the inputs when needed, so I don't think gpio-keys is the right choice. So I'm still with the hog + manual export with gpio number "solution".
Ideal scenario
I'm hoping to have something like this:
/ {
[...]
gpio-custom {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio_custom>;
my-input {
label = "my-input";
gpios = <&gpio5 10 GPIO_ACTIVE_HIGH>;
input;
};
my-output {
label = "my-output";
gpios = <&gpio5 11 GPIO_ACTIVE_LOW>;
output-high;
};
};
[...]
};
[...]
&iomuxc {
pinctrl-names = "default";
[...]
pinctrl_gpio_custom: gpiocustomgrp {
fsl,pins = <
MX8MP_IOMUXC_ECSPI2_SCLK__GPIO5_IO10 0x19
MX8MP_IOMUXC_ECSPI2_MOSI__GPIO5_IO11 0x19
>;
};
[...]
};
I've made several test adding compatible
, gpio-controller
, adding groups here and there, ..., but I've never been able to satisfy all my 3 requests.
Am I missing something? What are the correct things to add to have the in/out mapped and setup as desired?
Note
As said, I want the GPIO configuration to take place as soon as possible. After editing the kernel device tree, I will port the modifications to the u-boot device tree, too. So, I need a solution that can be compatible with u-boot, too. I'm running U-Boot 2021.04-lf_v2021.04+gf8002fcb58 (hope this is the correct info).