Using GPIO in u-boot with imx8qxp

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Using GPIO in u-boot with imx8qxp

1,230 Views
Anthony_R
Contributor II

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 ?

 

1 Reply

1,208 Views
Anthony_R
Contributor II

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 :

 

Spoiler
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 ?

 

0 Kudos
Reply