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.

AM62A7: Configure GPIO as input and read GPIO value from u-boot source code

Part Number: AM62A7

Tool/software:

Hi, 

Yocto SDK: 9.1.0

EVK: AM62A SK Evm

I want to read 3 gpio from u-boot source code and I want to set u-boot environment variable according to gpio status. How can I configure gpio as input and read status those gpios from u-boot source code? 

Regards,

Jay

  • Hi Jay,

    As Aparna mentioned, review these E2E FAQs.

    Just make sure that the U-Boot Device tree matches the Linux device tree so there are no unexpected errors.

    If you are trying to set the GPIOs in evm.c, then there is no sample code for this.

    Thanks,

    Anshu

  • Hi, 

    Thank you Aparna for references. 

    If you are trying to set the GPIOs in evm.c, then there is no sample code for this

    Yes, Anshu, We are trying to read board variant gpio from evm.c and then will set the dtb overlays variable. We have matched kernel and u-boot device trees. 

    Let us know if you come across any such references. 

    Regards,

    Jay

  • Hi Jay,

    You can look at other board evm.c files for some reference like this from omap3: https://git.ti.com/cgit/ti-u-boot/ti-u-boot/tree/board/ti/omap3evm/evm.c?h=ti-u-boot-2023.04

    This is the full list of device's evm.c listed here: https://git.ti.com/cgit/ti-u-boot/ti-u-boot/tree/board/ti?h=ti-u-boot-2023.04

    Best Regards,

    Anshu

  • Hi Jay,

    Looking a bit further, you can refer to these GPIO functions in the U-Boot include files: https://git.ti.com/cgit/ti-u-boot/ti-u-boot/tree/include/asm-generic/gpio.h?h=ti-u-boot-2023.04

    Note that some of them a deprecated so be aware of which functions can be used.

    Thank,

    Anshu

  • Hi Anshu, 

    I am able to read the gpio from u-boot source. below is the approach that I followed.

    gpio read from u-boot command line:

    => gpio status -a
    Bank gpio@600000_:
    gpio@600000_0: input: 0 [ ]
    gpio@600000_1: input: 0 [ ]
    gpio@600000_2: input: 0 [ ]
    gpio@600000_3: input: 0 [ ]
    gpio@600000_4: input: 0 [ ]
    gpio@600000_5: input: 0 [ ]
    gpio@600000_6: input: 0 [ ]
    gpio@600000_7: input: 0 [ ]
    gpio@600000_8: input: 0 [ ]
    gpio@600000_9: input: 0 [ ]
    gpio@600000_10: input: 0 [ ]
    gpio@600000_11: input: 0 [ ]
    gpio@600000_12: input: 0 [ ]
    gpio@600000_13: input: 0 [ ]
    gpio@600000_14: input: 0 [ ]
    gpio@600000_15: input: 1 [ ]
    gpio@600000_16: input: 1 [ ]
    gpio@600000_17: input: 0 [ ]
    gpio@600000_18: input: 1 [ ]
    gpio@600000_19: input: 0 [ ]
    gpio@600000_20: input: 0 [ ]
    gpio@600000_21: input: 1 [ ]
    gpio@600000_22: input: 0 [ ]
    gpio@600000_23: input: 0 [ ]
    gpio@600000_24: input: 1 [ ]
    gpio@600000_25: input: 1 [ ]
    gpio@600000_26: input: 0 [ ]
    gpio@600000_27: input: 1 [ ]
    gpio@600000_28: input: 0 [ ]
    gpio@600000_29: input: 0 [ ]
    gpio@600000_30: input: 0 [ ]
    gpio@600000_31: input: 0 [ ]
    gpio@600000_32: input: 0 [ ]
    gpio@600000_33: input: 0 [ ]
    gpio@600000_34: input: 0 [ ]
    gpio@600000_35: input: 0 [ ]
    gpio@600000_36: input: 0 [ ]
    gpio@600000_37: input: 0 [ ]
    gpio@600000_38: input: 0 [ ]
    gpio@600000_39: input: 0 [ ]
    gpio@600000_40: input: 0 [ ]
    gpio@600000_41: input: 0 [ ]
    gpio@600000_42: input: 0 [ ]
    gpio@600000_43: input: 0 [ ]
    gpio@600000_44: input: 0 [ ]
    gpio@600000_45: input: 0 [ ]
    gpio@600000_46: input: 0 [ ]
    gpio@600000_47: input: 0 [ ]
    gpio@600000_48: input: 0 [ ]
    gpio@600000_49: input: 0 [ ]
    gpio@600000_50: input: 0 [ ]
    gpio@600000_51: input: 0 [ ]
    gpio@600000_52: input: 0 [ ]
    gpio@600000_53: input: 0 [ ]
    gpio@600000_54: input: 0 [ ]
    gpio@600000_55: input: 0 [ ]
    gpio@600000_56: input: 0 [ ]
    gpio@600000_57: input: 0 [ ]
    gpio@600000_58: input: 0 [ ]
    gpio@600000_59: input: 0 [ ]
    gpio@600000_60: input: 0 [ ]
    gpio@600000_61: input: 0 [ ]
    gpio@600000_62: input: 0 [ ]
    gpio@600000_63: input: 0 [ ]
    gpio@600000_64: input: 0 [ ]
    gpio@600000_65: input: 0 [ ]
    gpio@600000_66: input: 0 [ ]
    gpio@600000_67: input: 0 [ ]
    gpio@600000_68: input: 0 [ ]
    gpio@600000_69: input: 0 [ ]
    gpio@600000_70: input: 0 [ ]
    gpio@600000_71: input: 0 [ ]
    gpio@600000_72: input: 0 [ ]
    gpio@600000_73: input: 0 [ ]
    gpio@600000_74: input: 0 [ ]
    gpio@600000_75: input: 0 [ ]
    gpio@600000_76: input: 0 [ ]
    gpio@600000_77: input: 0 [ ]
    gpio@600000_78: input: 0 [ ]
    gpio@600000_79: input: 0 [ ]
    gpio@600000_80: input: 0 [ ]
    gpio@600000_81: input: 1 [ ]
    gpio@600000_82: input: 0 [ ]
    gpio@600000_83: input: 1 [ ]
    gpio@600000_84: input: 1 [ ]
    gpio@600000_85: input: 1 [ ]
    gpio@600000_86: input: 0 [ ]
    gpio@600000_87: input: 1 [x] gpio@600000_87
    gpio@600000_88: input: 0 [x] gpio@600000_88
    gpio@600000_89: input: 0 [x] gpio@600000_89
    gpio@600000_90: input: 0 [ ]
    gpio@600000_91: input: 0 [ ]
    
    Bank gpio@601000_:
    gpio@601000_0: input: 0 [ ]
    gpio@601000_1: input: 0 [ ]
    gpio@601000_2: input: 0 [ ]
    gpio@601000_3: input: 0 [ ]
    gpio@601000_4: input: 0 [ ]
    gpio@601000_5: input: 0 [ ]
    gpio@601000_6: input: 0 [ ]
    gpio@601000_7: input: 0 [ ]
    gpio@601000_8: input: 0 [ ]
    gpio@601000_9: input: 0 [ ]
    gpio@601000_10: input: 0 [ ]
    gpio@601000_11: input: 0 [ ]
    gpio@601000_12: input: 0 [ ]
    gpio@601000_13: input: 0 [ ]
    gpio@601000_14: input: 0 [ ]
    gpio@601000_15: input: 0 [ ]
    gpio@601000_16: input: 0 [ ]
    gpio@601000_17: input: 0 [ ]
    gpio@601000_18: input: 0 [ ]
    gpio@601000_19: input: 0 [ ]
    gpio@601000_20: input: 1 [ ]
    gpio@601000_21: input: 0 [ ]
    gpio@601000_22: input: 0 [ ]
    gpio@601000_23: input: 0 [ ]
    gpio@601000_24: input: 0 [ ]
    gpio@601000_25: input: 0 [ ]
    gpio@601000_26: input: 0 [ ]
    gpio@601000_27: input: 0 [ ]
    gpio@601000_28: input: 0 [ ]
    gpio@601000_29: input: 0 [ ]
    gpio@601000_30: input: 0 [ ]
    gpio@601000_31: input: 0 [ ]
    gpio@601000_32: input: 1 [ ]
    gpio@601000_33: input: 1 [ ]
    gpio@601000_34: input: 1 [ ]
    gpio@601000_35: input: 1 [ ]
    gpio@601000_36: input: 1 [ ]
    gpio@601000_37: input: 1 [ ]
    gpio@601000_38: input: 1 [ ]
    gpio@601000_39: input: 1 [ ]
    gpio@601000_40: input: 1 [ ]
    gpio@601000_41: input: 1 [ ]
    gpio@601000_42: input: 0 [ ]
    gpio@601000_43: input: 0 [ ]
    gpio@601000_44: input: 0 [ ]
    gpio@601000_45: input: 0 [ ]
    gpio@601000_46: input: 0 [ ]
    gpio@601000_47: input: 0 [ ]
    gpio@601000_48: input: 0 [ ]
    gpio@601000_49: input: 0 [ ]
    gpio@601000_50: input: 0 [ ]
    gpio@601000_51: input: 0 [ ]

    Shown gpio name can be used with dm_gpio_xxx function in u-boot to set and get value as below:

    int board_init(void)
    {
        int ret;
        struct gpio_desc desc;
    
        memset(&desc, 0, sizeof(desc));
        ret = dm_gpio_lookup_name("gpio@600000_87", &desc);
        if (ret < 0) {
            pr_err("Failed to lookup gpio : %d\n", ret);
            return ret;
        }
    
        /* Request GPIO, simply re-using the name as label */
        ret = dm_gpio_request(&desc, "gpio@600000_87");
        if (ret < 0) {
            pr_err("Failed to request gpio : %d\n", ret);
            return ret;
        }
    
        ret = dm_gpio_set_dir_flags(&desc, GPIOD_IS_IN);
        if (ret < 0) {
            pr_err("Failed to set gpio direction : %d\n", ret);
            return ret;
        }
    
        ret = dm_gpio_get_value(&desc);
        if (ret < 0) {
            pr_err("Failed to read gpio value : %d\n", ret);
            return ret;
        }
        printk("Variant 0 gpio : %d\n",ret);
    
        memset(&desc, 0, sizeof(desc));
        ret = dm_gpio_lookup_name("gpio@600000_88", &desc);
        if (ret < 0) {
            pr_err("Failed to lookup gpio : %d\n", ret);
            return ret;
        }
    
        /* Request GPIO, simply re-using the name as label */
        ret = dm_gpio_request(&desc, "gpio@600000_88");
        if (ret < 0) {
            pr_err("Failed to request gpio : %d\n", ret);
            return ret;
        }
    
        ret = dm_gpio_set_dir_flags(&desc, GPIOD_IS_IN);
        if (ret < 0) {
            pr_err("Failed to set gpio direction : %d\n", ret);
            return ret;
        }
    
        ret = dm_gpio_get_value(&desc);
        if (ret < 0) {
            pr_err("Failed to read gpio value : %d\n", ret);
            return ret;
        }
        printk("Variant 1 gpio : %d\n",ret);
    
        memset(&desc, 0, sizeof(desc));
        ret = dm_gpio_lookup_name("gpio@600000_89", &desc);
        if (ret < 0) {
            pr_err("Failed to lookup gpio : %d\n", ret);
            return ret;
        }
    
        /* Request GPIO, simply re-using the name as label */
        ret = dm_gpio_request(&desc, "gpio@600000_89");
        if (ret < 0) {
            pr_err("Failed to request gpio : %d\n", ret);
            return ret;
        }
    
        ret = dm_gpio_set_dir_flags(&desc, GPIOD_IS_IN);
        if (ret < 0) {
            pr_err("Failed to set gpio direction : %d\n", ret);
            return ret;
        }
    
        ret = dm_gpio_get_value(&desc);
        if (ret < 0) {
            pr_err("Failed to read gpio value : %d\n", ret);
            return ret;
        }   
        printk("Variant 2 gpio : %d\n",ret);
    
        return 0;
    }

    Same gpio entry need to be added in device tree as well:

    &main_pmx0 {
        gpio0_pins_default: gpio0-pins-default {
            pinctrl-single,pins = <
                AM62AX_IOPAD(0x0164, PIN_INPUT, 7) /* (Y19) RGMII2_TX_CTL.GPIO0_87 -> IOBRD_VAR0 */
                AM62AX_IOPAD(0x0168, PIN_INPUT, 7) /* (AB19) RGMII2_TXC.GPIO0_88 -> IOBRD_VAR1 */
                AM62AX_IOPAD(0x016c, PIN_INPUT, 7) /* (AA19) RGMII2_TD0.GPIO0_89 -> IOBRD_VAR2 */
            >;
        };
    };
    
    &main_gpio0 {
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&gpio0_pins_default>;
    };

    My query:

    My motive was to set kernel device tree overlay file using u-boot environment variable dynamically as different board variant's same uart has rs232 and rs485 interfaces. So, according to that we need to load particular dtbo. I used env_set() function from u-boot source as below according to the board variant gpio:

        printk("environment variable after : %s\n",env_get("name_overlays"));
        ret = env_set("name_overlays", "ti/k3-am62a7-sk-rs485.dtb0");
        if(ret != 0) {
            pr_err("Failed to set u-boot environment variable : %d\n", ret);
            return ret;
        }
        printk("environment variable after : %s\n",env_get("name_overlays"));

    "name_overlays" variable is not getting set. It is having the same value even after evn_set() function call. Do think if anything is wrong with my approach? Please suggest if there is any other approach can achieve the same.

    Regards,

    Jay

  • Hello Jay,

    I am currently returning to office and will get back to you as soon as possible. Please ping this thread by Thursday if you haven't received a response.

    Thanks,

    Anshu

  • Hi Jay,

    The device tree changes seems fine and looks like its reflected in gpio status -a.

    Let me loop in the U-Boot expert to comment further.

    Thanks,

    Anshu

  • Hi Anshu, 

    I am able to change the reading the gpio status in u-boot as below:\

    --- a/board/ti/am62ax/am62ax.env
    +++ b/board/ti/am62ax/am62ax.env
    @@ -23,3 +23,4 @@ bootdir=/boot
     rd_spec=-
     rproc_fw_binaries= 0 /lib/firmware/am62a-mcu-r5f0_0-fw 1 /lib/firmware/am62a-c71_0-fw
     bootdelay=1
    +set_overlays= if gpio input gpio@600000_87; then if gpio input gpio@600000_88; then if gpio input gpio@600000_89; then ; else setenv name_overlays sick-k3-am62a7-sk-rs232.dtbo; fi; else if gpio input gpio@600000_89; then ; else setenv name_overlays sick-k3-am62a7-sk-rs485.dtbo; fi; fi; fi;

    I am calling the set_overlay variable from BOOTCOMMAND as below:

    CONFIG_BOOTCOMMAND="run set_overlays; run envboot; run distro_bootcmd;"

    This will set overlays at run time based on the board variant gpios value. 

    Thank you for all the help. you can close this thread.

    Regards,

    Jay