GPIO SYSFS DRAFT

From Variscite Wiki
Revision as of 05:29, 24 April 2023 by Alifer (talk | contribs) (Initial draft of the GPIO SYSFS wiki page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
VAR-SOM-MX8X GPIO

GPIO state

The current state of the system's GPIOs can be obtained in user-mode, as shown in the following example:

# cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 0-31, parent: platform/5d080000.gpio, 5d080000.gpio:
 gpio-12  (                    |ov5640_mipi_reset   ) out hi    
 gpio-16  (                    |fsl_lpspi           ) in  hi    
 gpio-26  (                    |ov5640_mipi_pwdn    ) out lo    

gpiochip1: GPIOs 32-63, parent: platform/5d090000.gpio, 5d090000.gpio:
 gpio-32  (                    |fsl_lpspi           ) in  hi    
 gpio-34  (                    |phy-reset           ) out hi    
 gpio-39  (                    |reg_sd_pwr          ) out hi    
 gpio-60  (                    |reg_ethphy0         ) out hi    

gpiochip2: GPIOs 64-95, parent: platform/5d0a0000.gpio, 5d0a0000.gpio:

gpiochip3: GPIOs 96-127, parent: platform/5d0b0000.gpio, 5d0b0000.gpio:
 gpio-120 (                    |cam_buf_en          ) out hi    

gpiochip4: GPIOs 128-159, parent: platform/5d0c0000.gpio, 5d0c0000.gpio:
 gpio-149 (                    |usb_otg1_vbus       ) out hi    
 gpio-150 (                    |cd                  ) in  lo IRQ

gpiochip5: GPIOs 160-191, parent: platform/5d0d0000.gpio, 5d0d0000.gpio:
 gpio-169 (                    |connect             ) in  hi IRQ

gpiochip6: GPIOs 192-223, parent: platform/5d0e0000.gpio, 5d0e0000.gpio:

gpiochip7: GPIOs 224-255, parent: platform/5d0f0000.gpio, 5d0f0000.gpio:

gpiochip8: GPIOs 504-511, parent: i2c/1-0020, pca9534, can sleep:
 gpio-504 (                    |heartbeat           ) out lo    
 gpio-505 (                    |Back                ) in  hi IRQ
 gpio-506 (                    |Home                ) in  hi IRQ
 gpio-507 (                    |Menu                ) in  hi IRQ
 gpio-508 (                    |usb3_sel            ) out lo    
 gpio-509 (                    |phy-reset           ) out hi    
 gpio-510 (                    |reg_vselect         ) out hi    
 gpio-511 (                    |reg_ethphy1         ) out hi    

Each GPIO is defined as in or out and the state is shown as lo or hi.
For example pin 150 is the SD card card-detect. When an SD card is plugged in, the state will be:

gpio-150  (                    |cd                  ) in  lo IRQ

When the SD card is removed, the state will be:

gpio-150  (                    |cd                  ) in  hi IRQ

Manipulating a single GPIO via /sys/class/gpio

Using a command line or a script

GPIOs in i.MX are grouped in groups of 32 pins.
For example, GPIO0_3 belongs to the first group, pin 3. Its absolute number will be 3.
GPIO4_21 will be 4*32+21=149.
Assuming this GPIO is defined in your device tree, the following is an example of how to use it from userspace.

To export the GPIO for userspace use:

# echo 149 > /sys/class/gpio/export


To configure as output:

# echo out > /sys/class/gpio/gpio149/direction

Set GPIO high:

# echo 1 > /sys/class/gpio/gpio149/value

Set GPIO low:

# echo 0 > /sys/class/gpio/gpio149/value


To configure as input:

# echo in > /sys/class/gpio/gpio149/direction

Read the current value:

# cat /sys/class/gpio/gpio149/value


To free the GPIO after you're done using it:

# echo 149 > /sys/class/gpio/unexport

Using a C application

All of the command line operations above can be translated to C code:
Reserve (export) the GPIO:

#define IMX_GPIO_NR(port, index)    ((port)*32)+((index)&31))

int fd;
char buf[MAX_BUF]; 
int gpio = IMX_GPIO_NR(4, 21); /* Just an example */

fd = open("/sys/class/gpio/export", O_WRONLY);

sprintf(buf, "%d", gpio); 

write(fd, buf, strlen(buf));

close(fd);

Set the GPIO direction:

sprintf(buf, "/sys/class/gpio/gpio%d/direction", gpio);

fd = open(buf, O_WRONLY);

/* Set out direction */
write(fd, "out", 3); 
/* Set in direction */
write(fd, "in", 2); 

close(fd);

In case of out direction set the GPIO value:

sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);

fd = open(buf, O_WRONLY);

/* Set GPIO high status */
write(fd, "1", 1); 
/* Set GPIO low status */
write(fd, "0", 1); 

close(fd);

In case of in direction get the current GPIO value:

char value;

sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);

fd = open(buf, O_RDONLY);

read(fd, &value, 1);

if (value == '0') { 
     /* Current GPIO status low */
} else {
     /* Current GPIO status high */
}

close(fd);

Once finished, free (unexport) the GPIO:

fd = open("/sys/class/gpio/unexport", O_WRONLY);

sprintf(buf, "%d", gpio);

write(fd, buf, strlen(buf));

close(fd);

Important notes:

  • Remember that after the first read operation, the file pointer will move to the next position in the file, so to get a correct value for each read operation you simply have to set the file pointer at the beginning of the file before reading by using the following command:
lseek(fd, 0, SEEK_SET);
  • This is only a short example. If you want to use it in your code, remember to add error handling to it.