This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ] TDA4VM/DRA829/AM65xx: Linux: Configuring GPIOs

Part Number: TDA4VM

How can I configure GPIOs on the TDA4 EVM using the following methods:

  1. Using sysfs
  2. From Device tree

  • -1- 

    Using sysfs: (https://www.kernel.org/doc/Documentation/gpio/sysfs.txt)

    Steps:

    1. Identify the GPIO chip
    2. Export the GPIO number you want to toggle from that GPIO chip
    3. Set direction, Value and other attributes for the exported GPIO

    Let us assume we want to toggle GPIO0_127

    Step1

    Run the following:

    root@j7-evm:~# find /proc/device-tree/__symbols__/ | grep gpio
    /proc/device-tree/__symbols__/main_gpio_intr
    /proc/device-tree/__symbols__/main_gpio7
    /proc/device-tree/__symbols__/main_gpio5
    /proc/device-tree/__symbols__/wkup_gpio0
    /proc/device-tree/__symbols__/main_gpio3
    /proc/device-tree/__symbols__/main_gpio1
    /proc/device-tree/__symbols__/gpio_keys
    /proc/device-tree/__symbols__/wkup_gpio_intr
    /proc/device-tree/__symbols__/main_gpio6
    /proc/device-tree/__symbols__/wkup_gpio1
    /proc/device-tree/__symbols__/main_gpio4
    /proc/device-tree/__symbols__/main_gpio2
    /proc/device-tree/__symbols__/main_gpio0

    Read the content to find the path inside DT

    root@j7-evm:~# cat /proc/device-tree/__symbols__/main_gpio0
    /interconnect@100000/gpio@600000

    Now that you know that the gpiochip you are looking for is for the device gpio@600000

    You can check which gpiochip is registered with that platform device.

    root@j7-evm:~# ls -la /sys/class/gpio/
    drwxr-xr-x    2 root     root             0 Feb 17 08:38 .
    drwxr-xr-x   60 root     root             0 Feb 17 08:38 ..
    --w-------    1 root     root         65536 Feb 17 08:38 export
    lrwxrwxrwx    1 root     root             0 Feb 17 08:38 gpiochip0 -> ../../devices/platform/interconnect@100000/interconnect@100000:interconnect@28380000/42110000.gpio/gpio/gpiochip0
    lrwxrwxrwx    1 root     root             0 Feb 17 08:38 gpiochip212 -> ../../devices/platform/interconnect@100000/601000.gpio/gpio/gpiochip212
    lrwxrwxrwx    1 root     root             0 Feb 17 08:38 gpiochip448 -> ../../devices/platform/interconnect@100000/2010000.i2c/i2c-4/4-0020/gpio/gpiochip448
    lrwxrwxrwx    1 root     root             0 Feb 17 08:38 gpiochip456 -> ../../devices/platform/interconnect@100000/2060000.i2c/i2c-9/9-0020/gpio/gpiochip456
    lrwxrwxrwx    1 root     root             0 Feb 17 08:38 gpiochip464 -> ../../devices/platform/interconnect@100000/2030000.i2c/i2c-6/6-0020/gpio/gpiochip464
    lrwxrwxrwx    1 root     root             0 Feb 17 08:38 gpiochip472 -> ../../devices/platform/interconnect@100000/2000000.i2c/i2c-3/3-0022/gpio/gpiochip472
    lrwxrwxrwx    1 root     root             0 Feb 17 08:38 gpiochip496 -> ../../devices/platform/interconnect@100000/2000000.i2c/i2c-3/3-0020/gpio/gpiochip496
    lrwxrwxrwx    1 root     root             0 Feb 17 08:38 gpiochip84 -> ../../devices/platform/interconnect@100000/600000.gpio/gpio/gpiochip84
    --w-------    1 root     root         65536 Feb 17 08:38 unexport

    Now you know that gpiochip84 represents main_gpio0 or GPIO0

    Step2 and Step3

    Add 127 to this, i.e. 84 + 127 = 211

    root@j7-evm:~# cd /sys/class/gpio/
    root@j7-evm:/sys/class/gpio# echo 211 > export
    root@j7-evm:/sys/class/gpio# cd gpio211
    root@j7-evm:/sys/class/gpio/gpio211# echo out > direction
    root@j7-evm:/sys/class/gpio/gpio100# echo 1 > value

    Above should export the GPIO and you can do read/writes.

    NOTE:

    However, please make sure that the corresponding pinmux is configured in the DTS.

    Use pinmux tool to find out the exact register for programming. Recommendation is to add a devicetree entry for pinmux.

     

    -2-

    Using Device tree

    1. Add PINMUX for the GPIO (use PINMUX tool for this - https://www.ti.com/tool/PINMUXTOOL) also there is an FAQ https://e2e.ti.com/support/processors/f/791/t/927526 to help in this.
    2. Hog the GPIO in the Device tree

    Let us assume we want to toggle GPIO0_127

    Step1: In the board specific DTS - k3-j721e-common-proc-board.dts add the following

     &main_pmx0 {
    +
    +	mygpio1_pins_default: mygpio1_pins_default {
    +		pinctrl-single,pins = <
    +			J721E_IOPAD(0x200, PIN_INPUT, 7) /* (AC4) UART1_CTSn.GPIO0_127 */
    +		>;
    +	};
    }

    Step2: In the same board specific DTS, hog the GPIO (https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio.txt)

    +&m_can2 {
    +	status = "okay";
    +	pinctrl-names = "default";
    +	pinctrl-0 = <&mcan2_gpio_pins_default &mygpio1_pins_default>; /* mygpio1_pins_default for PINMUXing the GPIO0_127 */
    +	can-transceiver {
    +		max-bitrate = <5000000>;
    +	};
    +};
    
    +	mygpio1_pins_default: mygpio1_pins_default {
    +		pinctrl-single,pins = <
    +			J721E_IOPAD(0x200, PIN_INPUT, 7) /* (AC4) UART1_CTSn.GPIO0_127 */
    +		>;
    +	};

    The above will do a one time configuration of the GPIO from the kernel. Note that GPIOs already being used can not be exported using the sysfs. So in case you do the above, you will not be able to export this GPIO (as mentioned in 1) and change it back again.

    The sysfs interface can be used for quick testing and then the changes can be made to the device tree. Please also note that any of the changes will take in effect only when you have the correct Pinmux.

    Regards,

    Karan

  • Along with SoC GPIOs we can also configure GPIOs coming from I2C expanders.

    One way to do that is to hog the GPIO (https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio.txt) in the same way as we did before. There are examples existing in the k3-j721e-common-proc-board.dts

    The other way is to do I2C transactions from the user-space to do some tests before actually moving that code to the Device Tree.

    We can use i2c-get and i2c-set commands.

    For that we need to do the following steps:

    1. Get the chip number (schematics)
    2. Get the i2c bus number (as registered by the kernel, this may be different from the actual i2c bus number mentioned in the schematics and device tree)
    3. Run the i2c-set command to set the GPIOs coming from the I2C GPIO expander.

    Example:

    Let us take an example where we want to set i2c0 chip 0x22.

    k3-j721e-main.dtsi:

    1413         main_i2c0: i2c@2000000 {
    1414                 compatible = "ti,j721e-i2c", "ti,omap4-i2c";
    1415                 reg = <0x0 0x2000000 0x0 0x100>;
    1416                 interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
    1417                 #address-cells = <1>;
    1418                 #size-cells = <0>;
    1419                 clock-names = "fck";
    1420                 clocks = <&k3_clks 187 0>;
    1421                 power-domains = <&k3_pds 187 TI_SCI_PD_SHARED>;
    1422         };
    

    from the user-space run the following:

    root@j7-evm:~# dmesg | grep i2c
    [    0.685447] i2c /dev entries driver
    [    0.823948] omap_i2c 40b00000.i2c: bus 0 rev0.12 at 100 kHz
    [    0.829869] omap_i2c 40b10000.i2c: bus 1 rev0.12 at 100 kHz
    [    0.835846] omap_i2c 42120000.i2c: bus 2 rev0.12 at 100 kHz
    [    0.928222] omap_i2c 2000000.i2c: bus 3 rev0.12 at 400 kHz
    [    0.934237] omap_i2c 2010000.i2c: bus 4 rev0.12 at 400 kHz
    [    0.940117] omap_i2c 2020000.i2c: bus 5 rev0.12 at 100 kHz
    [    0.986345] omap_i2c 2030000.i2c: bus 6 rev0.12 at 400 kHz
    [    0.992200] omap_i2c 2040000.i2c: bus 7 rev0.12 at 100 kHz
    [    0.998053] omap_i2c 2050000.i2c: bus 8 rev0.12 at 100 kHz
    [    1.040217] omap_i2c 2060000.i2c: bus 9 rev0.12 at 400 kHz

    We see i2c@2000000 -> main_i2c0 -> i2c bus 3 here. 

    So in the i2c-set command we need to use this number "3" to access the chip connected at 0x22 to main_i2c0.


    Regards,

    Karan