GPIO Utility on I-Pi SMARC LEC-EL

This document provides detailed instructions for utilizing the gpio pins on the I-Pi SMARC LEC-EL module based on Ubuntu.

Prerequisites

  • GPIO libraries are included with our image by default.
  • Power up the targeted device with all the necessary cables, such as HDMI, keyboard, mouse, and ethernet cable.

Utilizing the GPIO Pins with Linux

  • Open the terminal and type the following command to navigate to gpio

    cd /sys/class/gpio
  • The /sys/class/gpio can only be accessed as root by default, so log in as root.

    sudo su 
  • To view the details of Gpiochip.

    $ gpiodetect

    root@adlink-LEC-EL:/home/adlink# gpiodetect
    gpiochip0 [INTC1020:00] (67 lines)
    gpiochip1 [INTC1020:01] (113 lines)
    gpiochip2 [INTC1020:03] (47 lines)
    gpiochip3 [INTC1020:04] (80 lines)
    gpiochip4 [INTC1020:05] (8 lines)
    root@adlink-LEC-EL:/home/adlink#

    (or)

    $ cat /sys/kernel/debug/gpio

    root@adlink-LEC-EL:/home/adlink# cat /sys/kernel/debug/gpio
    gpiochip4: GPIOs 197-204, parent: platform/INTC1020:05, INTC1020:05:

    gpiochip3: GPIOs 205-284, parent: platform/INTC1020:04, INTC1020:04:

    gpiochip2: GPIOs 285-331, parent: platform/INTC1020:03, INTC1020:03:

    gpiochip1: GPIOs 332-444, parent: platform/INTC1020:01, INTC1020:01:

    gpiochip0: GPIOs 445-511, parent: platform/INTC1020:00, INTC1020:00:
    root@adlink-LEC-EL:/home/adlink#

  • To export the GPIO pin.

    echo N > export (N should replace with gpio chip base number)

    root@adlink-LEC-EL:/sys/class/gpio# echo 286 > export
    root@adlink-LEC-EL:/sys/class/gpio# ls
    export gpio286 gpiochip197 gpiochip205 gpiochip285 gpiochip332 gpiochip445 unexport
    root@adlink-LEC-EL:/sys/class/gpio#
  • To read the exported pin details, you can use the command cat.

    cd gpioN                   (N should replace with gpio chip base number)
    ls
    cat direction
    cat value

    root@adlink-LEC-EL:/sys/class/gpio# cd gpio286
    root@adlink-LEC-EL:/sys/class/gpio/gpio286# ls
    active_low device direction edge power subsystem uevent value
    root@adlink-LEC-EL:/sys/class/gpio/gpio286# cat direction
    in
    root@adlink-LEC-EL:/sys/class/gpio/gpio286# cat value
    0
    root@adlink-LEC-EL:/sys/class/gpio/gpio286#
  • To read the direction and value of a pin.

    Direction:

    cat /sys/class/gpio/gpioN/direction (N should replace with gpio chip base number)

    root@adlink-LEC-EL:/# cat /sys/class/gpio/gpio286/direction
    in
    or

    cd /sys/class/gpio/gpioN
    cat direction

    root@adlink-LEC-EL:/home/adlink# cd /sys/class/gpio/gpio286
    root@adlink-LEC-EL:/sys/class/gpio/gpio286# cat direction
    in
    root@adlink-LEC-EL:/sys/class/gpio/gpio286#

    Value:

    cat /sys/class/gpio/gpioN/value (N should replace with gpio chip base number)

    root@adlink-LEC-EL:/# cat /sys/class/gpio/gpio286/value
    0
    root@adlink-LEC-EL:/#

    or
    cd /sys/class/gpio/gpioN
    cat value
    root@adlink-LEC-EL:/sys/class/gpio/gpio286# cat value
    0
    root@adlink-LEC-EL:/sys/class/gpio/gpio286#
  • To write the direction of a pin to input.

    echo in > /sys/class/gpio/gpioN/direction  (N should replace with gpio chip base number)

    root@adlink-LEC-EL:/# echo in > /sys/class/gpio/gpio286/direction
    root@adlink-LEC-EL:/# cat /sys/class/gpio/gpio286/direction
    in
    root@adlink-LEC-EL:/#

    or

    cd /sys/class/gpio/gpioN
    echo in> direction

    root@adlink-LEC-EL:/home/adlink# cd /sys/class/gpio/gpio286
    root@adlink-LEC-EL:/sys/class/gpio/gpio286# echo in > direction
    root@adlink-LEC-EL:/sys/class/gpio/gpio286# cat direction
    in
    root@adlink-LEC-EL:/sys/class/gpio/gpio286#

  • To write the direction of a pin to output.

    echo out > /sys/class/gpio/gpioN/direction  (N should replace with gpio chip base number)

    root@adlink-LEC-EL:/# echo out > /sys/class/gpio/gpio286/direction
    root@adlink-LEC-EL:/# cat /sys/class/gpio/gpio286/direction
    out
    root@adlink-LEC-EL:/#


    or

    cd /sys/class/gpio/gpioN
    echo out> direction

    root@adlink-LEC-EL:/home/adlink# cd /sys/class/gpio/gpio286
    root@adlink-LEC-EL:/sys/class/gpio/gpio286# echo out > direction
    root@adlink-LEC-EL:/sys/class/gpio/gpio286# cat direction
    out
    root@adlink-LEC-EL:/sys/class/gpio/gpio286#
  • To write the value of a pin to a high.

    Note: Make sure the direction is out when trying to change the value to high or low.

    echo 1 > /sys/class/gpio/gpioN/value     (N should replace with gpio chip base number)


    root@adlink-LEC-EL:/# echo 1 > /sys/class/gpio/gpio286/value
    root@adlink-LEC-EL:/# cat /sys/class/gpio/gpio286/value
    1
    root@adlink-LEC-EL:/#


    or
    cd /sys/class/gpio/gpioN
    echo 1 > value
    root@adlink-LEC-EL:/sys/class/gpio/gpio286# echo 1 > value
    root@adlink-LEC-EL:/sys/class/gpio/gpio286# cat value
    1
    root@adlink-LEC-EL:/sys/class/gpio/gpio286#
  • To write the value of a pin to a low.

    Note: Make sure the direction is out when you are trying to change the value to high or low.

    echo 0 > /sys/class/gpio/gpioN/value

    root@adlink-LEC-EL:/# echo 0 > /sys/class/gpio/gpio286/value
    root@adlink-LEC-EL:/# cat /sys/class/gpio/gpio286/value
    0
    root@adlink-LEC-EL:/#


    or

    cd /sys/class/gpio/gpioN
    echo 0 > value
    root@adlink-LEC-EL:/sys/class/gpio/gpio286# echo 0 > value
    root@adlink-LEC-EL:/sys/class/gpio/gpio286# cat value
    0
    root@adlink-LEC-EL:/sys/class/gpio/gpio286#

Access I2C GPIO Expander SX1509

The SX1509 I2C GPIO expander, connected to the ADLINK I2C bus, can be accessed exclusively through the ADLINK SEMA Utility.

ADLINK SEMA Utility Installation on Ubuntu

  • It provides a set of functions to control GPIO pins.
  • Only supports the specific external GPIO controller: SX1509 I/O expander on LEC-EL Module.

Please follow the steps below to install the SEMA-4.x EC Package in Ubuntu.

sudo apt install build-essential git hexer i2c-tools
semainstall1
sudo apt-get install uuid-dev
semainstal2
git clone https://github.com/ADLINK/sema-linux.git -b sema-ec
cd sema-linux
semainstall3
sudo make
sudo make install
sudo modprobe -a adl-ec adl-ec-boardinfo adl-ec-vm adl-ec-wdt adl-ec-hwmon adl-ec-nvmem adl-ec-bklight adl-ec-i2c adl-ec-gpio adl-ec-nvmem-sec
semainstall4

Note: You can verify the ADLINK SEMA Utility by using i2cdetect -l

i2cdetect -l

adlink@adlink-LEC-EL:~/sema-linux$ i2cdetect -l
i2c-3 unknown Synopsys DesignWare I2C adapter N/A
i2c-1 unknown SMBus I801 adapter at efa0 N/A
i2c-6 unknown ADLINK BMC I2C adapter bus 2 N/A
i2c-4 unknown Synopsys DesignWare I2C adapter N/A
i2c-2 unknown Synopsys DesignWare I2C adapter N/A
i2c-0 unknown SMBus CMI adapter cmi N/A
i2c-7 unknown ADLINK BMC I2C adapter bus 3 N/A
i2c-5 unknown ADLINK BMC I2C adapter bus 1 N/A
adlink@adlink-LEC-EL:~/sema-linux$

Accessing SX1509 GPIO Pins

For Ubuntu users on the EC controller, after installing the SX1509 kernel driver on their target device, they can use the GPIO sysfs Interface and SEMA GPIO EAPI function to access GPIO pins.

After loading the kernel driver, configure the SX1509 GPIO driver by executing the following command.

echo sx1509 0x3e > /sys/bus/i2c/devices/i2c-X/new_device    (X is the i2c bus SEMA(BMC) and SX1509 connected)

root@adlink-LEC-EL:/home/adlink/sema-linux# echo sx1509 0x3e > /sys/bus/i2c/devices/i2c-6/new_device
root@adlink-LEC-EL:/home/adlink/sema-linux#

Note: Here, i2c-6 is used since SMBus is located at bus 6. 0x3e is the GPIO device slave address. Please refer to the screenshot below to find the i2c bus number and GPIO device address.

Using SEMA GPIO EAPI Function and GPIO sysfs Interface

To view the SEMA GPIO Commands

cd sema-linux
semautil /g
  • To view the details of Gpiochip

    root@adlink-LEC-EL:/home/adlink/sema-linux# cat /sys/kernel/debug/gpio 
    gpiochip5: GPIOs 189-196, parent: platform/adl-ec-acpi, adl-ec-gpio:

    gpiochip4: GPIOs 197-204, parent: platform/INTC1020:05, INTC1020:05:

    gpiochip3: GPIOs 205-284, parent: platform/INTC1020:04, INTC1020:04:

    gpiochip2: GPIOs 285-331, parent: platform/INTC1020:03, INTC1020:03:

    gpiochip1: GPIOs 332-444, parent: platform/INTC1020:01, INTC1020:01:

    gpiochip0: GPIOs 445-511, parent: platform/INTC1020:00, INTC1020:00:
    root@adlink-LEC-EL:/home/adlink/sema-linux#

    Note: Here, gpiochip5(gpiochip189) was the loaded one.

  • To export the GPIO pins in SX1509

    echo N > export (N should replace with gpio chip base number)

    root@adlink-LEC-EL:/sys/class/gpio# echo 189 > export
    root@adlink-LEC-EL:/sys/class/gpio# ls
    export gpio189 gpiochip189 gpiochip197 gpiochip205 gpiochip285 gpiochip332 gpiochip445 unexport
    root@adlink-LEC-EL:/sys/class/gpio# echo 190 > export
    root@adlink-LEC-EL:/sys/class/gpio#
  • To read the direction and value of a pin

    Using SEMA GPIO EAPI Function

    semautil /g get_direction [GPIO Bit]
    semautil /g get_level [GPIO Bit]

    root@adlink-LEC-EL:/home/adlink/sema-linux# semautil /g get_direction 7
    Direction : Input
    root@adlink-LEC-EL:/home/adlink/sema-linux# semautil /g get_level 7
    Level: High
    root@adlink-LEC-EL:/home/adlink/sema-linux#


    Using GPIO sysfs Interface

    cat direction (or) cat /sys/class/gpio/gpioN/direction
    cat value (or) cat /sys/class/gpio/gpioN/value


    root@adlink-LEC-EL:/sys/class/gpio/gpio189# cat direction
    in
    root@adlink-LEC-EL:/sys/class/gpio/gpio189# cat value
    0
    root@adlink-LEC-EL:/sys/class/gpio/gpio189#


  • To write the direction of a pin to input or output

    Using SEMA GPIO EAPI Function

    semautil /g set_direction [GPIO Bit] [0 - Output or 1 - Input]

    root@adlink-LEC-EL:/home/adlink/sema-linux# semautil /g get_direction 7
    Direction : Output
    root@adlink-LEC-EL:/home/adlink/sema-linux# semautil /g set_direction 7 1
    Direction updated successfully
    root@adlink-LEC-EL:/home/adlink/sema-linux# semautil /g get_direction 7
    Direction : Input
    root@adlink-LEC-EL:/home/adlink/sema-linux# semautil /g set_direction 7 0
    Direction updated successfully
    root@adlink-LEC-EL:/home/adlink/sema-linux# semautil /g get_direction 7
    Direction : Output
    root@adlink-LEC-EL:/home/adlink/sema-linux#


    Using GPIO sysfs Interface

    echo in > /sys/class/gpio/gpioN/direction (N should replace with gpio chip base number)
    echo out > /sys/class/gpio/gpioN/direction

    root@adlink-LEC-EL:/home/adlink/sema-linux# echo in > /sys/class/gpio/gpio195/direction
    root@adlink-LEC-EL:/home/adlink/sema-linux# semautil /g get_direction 7
    Direction : Input
    root@adlink-LEC-EL:/home/adlink/sema-linux# echo out > /sys/class/gpio/gpio195/direction
    root@adlink-LEC-EL:/home/adlink/sema-linux# semautil /g get_direction 7
    Direction : Output
    root@adlink-LEC-EL:/home/adlink/sema-linux#

    Note: Can check the successful execution by command cat /sys/kernel/debug/gpio

  • To write the value of a pin to low or high

    Note: Make sure the direction is out when you are trying to change the value to high or low.

    Using SEMA GPIO EAPI Function

    semautil /g set_level [GPIO Bit] [0 - Low or 1 - High]

    root@adlink-LEC-EL:/home/adlink/sema-linux# semautil /g set_level 7 1
    GPIO Level updated successfully
    root@adlink-LEC-EL:/home/adlink/sema-linux# semautil /g get_level 7
    Level: High
    root@adlink-LEC-EL:/home/adlink/sema-linux# semautil /g set_level 7 0
    GPIO Level updated successfully
    root@adlink-LEC-EL:/home/adlink/sema-linux# semautil /g get_level 7
    Level: Low
    root@adlink-LEC-EL:/home/adlink/sema-linux#


    Using GPIO sysfs Interface

    echo 1 > /sys/class/gpio/gpioN/value
    echo 0 > /sys/class/gpio/gpioN/value

    root@adlink-LEC-EL:/home/adlink/sema-linux# echo 0 > /sys/class/gpio/gpio195/value
    root@adlink-LEC-EL:/home/adlink/sema-linux#
    root@adlink-LEC-EL:/home/adlink/sema-linux# semautil /g get_level 7
    Level: Low
    root@adlink-LEC-EL:/home/adlink/sema-linux# echo 1 > /sys/class/gpio/gpio195/value
    root@adlink-LEC-EL:/home/adlink/sema-linux# semautil /g get_level 7
    Level: High
    root@adlink-LEC-EL:/home/adlink/sema-linux#
    setlevel