Hello,
I try to use a GPIO (connected to a micro switch) in my u-boot process as a boot option (with the u-boot commands "gpio input" and gpio read").
The GPIO I try to read is view under linux as GPIO 4, and declared in the linux dts as IMX8QXP_ESAI0_TX0_LSIO_GPIO0_IO04.
In my u-boot dts, I added a line SC_P_ESAI0_TX0_LSIO_GPIO0_IO04 0x00000060 under iomuxc -> imx8qxp-mek -> hoggrp.
I tried multiple syntax to get the GPIO, but that always end with the same error : GPIO: 'gpio0_4' not found
I so added some logs in gpio-uclass.c -> dm_gpio_lookup_name, and it looks like uclass_first_device(UCLASS_GPIO, &dev) return an empty list.
How could I use the GPIO in u-boot ? Is this a dts issue ?
Some news of my investigation on this topic : uclass_first_device fail because it try to probe every devices it can found, and stop at the first failure.
So I went away of the u-boot commands, and write my own function to read that GPIO, as following :
int get_gpio_cfg3_value(void){
char* devicename = "gpio@5d080000";
int offset = 4;
struct gpio_dev_priv *uc_priv = NULL;
struct udevice *dev;
int ret;
ret = uclass_find_device_by_name(UCLASS_GPIO,devicename,&dev);
if(ret){
printf("uclass_find_device_by_name failed with code %d\n", ret);
return -1;
}
ret = device_probe(dev);
if(ret){
printf("device_probe failed with code %d\n", ret);
return -1;
}
printf("dev found : %s %s %llx\n", dev->name, dev->driver->name, dev->uclass_priv);
uc_priv = dev->uclass_priv;
if(!uc_priv){
printf("dev_get_uclass_priv failed with code %d\n",ret);
return -1;
}
printf("Bank name : %s, number of GPIO in dev : %d\n", uc_priv->bank_name, uc_priv->gpio_count);
if (gpio_get_ops(dev)->request) {
ret = gpio_get_ops(dev)->request(dev, offset, "cfg3");
if(ret){
printf("gpio ops.request failed with code %d\n",ret);
return -1;
}
}else{
printf("gpio request is NULL\n");
}
ret = gpio_get_ops(dev)->direction_input(dev, offset);
if(ret){
printf("gpio direction_input failed with code %d\n",ret);
return -1;
}
int value = gpio_get_ops(dev)->get_value(dev, offset);
printf("Value of GPIO %s%d is %d\n", uc_priv->bank_name, offset, value);
if(gpio_get_ops(dev)->rfree){
ret = gpio_get_ops(dev)->rfree(dev, offset);
if(ret){
printf("gpio rfree failed with code %d\n",ret);
return -1;
}
}else{
printf("gpio rfree is NULL\n");
}
return value;
}
With that code, I obtain the following output, and all seems to work as expected :
dev found : gpio@5d080000 gpio_mxc fae62350
Bank name : GPIO0_, number of GPIO in dev : 32
gpio request is NULL
Value of GPIO GPIO0_4 is 0
gpio rfree is NUL
But, the value read is always 0, independent from my switch configuration. Under linux, using /sys/class/gpio/gpio4 works well.
I looked at mxc_gpio.c:mxc_gpio_get_value and I see no obvious reason for the real value to not being read as it just use readl on the register.
Should I add something in my dts file ? Is it normal that the mxc_gpio driver does not provide any request/rfree function ?