Reading GPIOs with DM_GPIO before device tree is loaded

Simon Glass sjg at chromium.org
Wed Jul 20 17:01:01 CEST 2022


Hi Hugo,

On Wed, 20 Jul 2022 at 04:54, Hugo Villeneuve <hugo at hugovil.com> wrote:
>
> Hi,
> in board_early_init_f(), i call a custom function get_som_revision() to read some GPIOs that are used to determine the SOM revision. This function basically sets the iomux, and then uses gpio_request/gpio_direction_input/gpio_get_value functions to read the GPIOs. Then, this SOM revision information is used in  board_fit_config_name_match() to decide which device tree to load.
>
> This works perfectly fine without CONFIG_DM_GPIO. However, if I enable CONFIG_DM_GPIO, it doesn't work anymore. There is an error when calling gpio_request().
>
> What is the correct way to read GPIOs BEFORE any device tree is loaded?
>
> My board uses an MX6Q SOM.
>
> Here is part of the code I am using:
>
> ========================================
> static iomux_v3_cfg_t const boardcfg_pads[] = {
>         MX6_PAD_DISP0_DAT15__GPIO5_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
>         MX6_PAD_DISP0_DAT8__GPIO4_IO29  | MUX_PAD_CTRL(NO_PAD_CTRL),
>         MX6_PAD_DISP0_DAT0__GPIO4_IO21  | MUX_PAD_CTRL(NO_PAD_CTRL),
>         MX6_PAD_ENET_RXD0__GPIO1_IO27   | MUX_PAD_CTRL(NO_PAD_CTRL),
>         MX6_PAD_ENET_RXD1__GPIO1_IO26   | MUX_PAD_CTRL(NO_PAD_CTRL),
> };
>
> static int som_revision = -1;
>
> static const int boardcfg_gpio[] = {
>         IMX_GPIO_NR(5, 9),
>         IMX_GPIO_NR(4, 29),
>         IMX_GPIO_NR(4, 21),
>         IMX_GPIO_NR(1, 27),
>         IMX_GPIO_NR(1, 26),
> };
>
> static void get_som_revision(void)
> {
>         int i;
>         int rc;
>
>         som_revision = 0;
>
>         SETUP_IOMUX_PADS(boardcfg_pads);
>
>         for (i = 0; i < ARRAY_SIZE(boardcfg_gpio); ++i) {
>                 int v;
>
>                 rc = gpio_request(boardcfg_gpio[i], "som-revision-gpio");
>                 if (rc) {
>                         printf("%s(): gpio request %d failed\n", __func__, i);
>                         som_revision = -1;
>                         return;
>                 }
>
>                 gpio_direction_input(boardcfg_gpio[i]);
>                 v = gpio_get_value(boardcfg_gpio[i]);
>
>                 if ((v == 0) || (v == 1))
>                         som_revision |= v << i;
>                 else {
>                         som_revision = -1;
>                         return;
>                 }
>         }
> }
>
> int board_early_init_f(void)
> {
>         setup_iomux_uart();
>         get_som_revision();
>
>         return 0;
> }
>
> ========================================

Well driver model needs the device tree to init, for example DM_GPIO
cannot operate without one unless you are hacking around with
platdata, which is a bit of a pain.

One option you might have is to use a general DT before relocation,
then figure out which one you really want to use and select that for
post relocation. That works better with driver model.

Regards,
Simon


More information about the U-Boot mailing list