Device tree setup GPIO - linux

Hi All,

I have an Open-q 410 board from Intrinsyc (very similar to dragonboard 410 in terms of SoC and other modules).

I am attempting to configure some BLSP pins as GPIOs, but am having some issues getting this working as I expect it to. Hopefully someone here can point me in the right direction :smiley:

What I am currently attempting to do:

  • Configure BLSP30 (GPIO11) as a GPIO setup as active low, and default state high.
  • Branching off tag debian-qcom-dragonboard410c-19.01

What I have done so far:

diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
index aac1da4f1d3c..b7f256375dc0 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
@@ -28,7 +28,7 @@
                i2c1    = &blsp_i2c6;
                i2c3    = &blsp_i2c4;
                spi0    = &blsp_spi5;
-               spi1    = &blsp_spi3;
+               // spi1 = &blsp_spi3;
        };
 
        chosen {
@@ -79,7 +79,7 @@
                        status = "okay";
 
                        adv_bridge: bridge@39 {
-                               status = "okay";
+                               status = "disabled";
 
                                compatible = "adi,adv7533";
                                reg = <0x39>;
@@ -193,6 +193,17 @@
                        };
                };
 
+               srs_gpios {
+                       pinctrl-0 = <&msmgpio_enable>;
+
+                       srs_gpio@1 {
+                               label = "ublox-power";
+                               gpios = <&msmgpio 11 GPIO_ACTIVE_LOW>;
+                       };
+
+               };
+
+
                sdhci@07824000 {
                        vmmc-supply = <&pm8916_l8>;
                        vqmmc-supply = <&pm8916_l5>;
@@ -239,7 +250,7 @@
                };
 
                mdss@1a00000 {
-                       status = "okay";
+                       status = "disabled";
 
                        mdp@1a01000 {
                                status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi
index 21d0822f1ca6..6795e3ecd297 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi
@@ -4,6 +4,19 @@
 
 &msmgpio {
 
+       msmgpio_enable: msmgpio_enable {
+               pinmux {
+                       pins = "gpio11";
+                       function = "gpio";
+               };
+               pinconf {
+                       pins = "gpio11";
+                       function = "gpio";
+                       drive-strength = <16>;
+                       output-high;
+               };
+       };
+
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 34d4b00e5c61..74528d223200 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -458,22 +458,22 @@
                        status = "disabled";
                };
 
-               blsp_spi3: spi@78b7000 {
-                       compatible = "qcom,spi-qup-v2.2.1";
-                       reg = <0x078b7000 0x600>;
-                       interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&gcc GCC_BLSP1_QUP3_SPI_APPS_CLK>,
-                                <&gcc GCC_BLSP1_AHB_CLK>;
-                       clock-names = "core", "iface";
-                       dmas = <&blsp_dma 9>, <&blsp_dma 8>;
-                       dma-names = "rx", "tx";
-                       pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&spi3_default>;
-                       pinctrl-1 = <&spi3_sleep>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
-               };
+               // blsp_spi3: spi@78b7000 {
+               //      compatible = "qcom,spi-qup-v2.2.1";
+               //      reg = <0x078b7000 0x600>;
+               //      interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+               //      clocks = <&gcc GCC_BLSP1_QUP3_SPI_APPS_CLK>,
+               //               <&gcc GCC_BLSP1_AHB_CLK>;
+               //      clock-names = "core", "iface";
+               //      dmas = <&blsp_dma 9>, <&blsp_dma 8>;
+               //      dma-names = "rx", "tx";
+               //      pinctrl-names = "default", "sleep";
+               //      pinctrl-0 = <&spi3_default>;
+               //      pinctrl-1 = <&spi3_sleep>;
+               //      #address-cells = <1>;
+               //      #size-cells = <0>;
+               //      status = "disabled";
+               // };
 
                blsp_spi4: spi@78b8000 {
                        compatible = "qcom,spi-qup-v2.2.1";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi
index b1ed8dcf7543..ea7ba876533a 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi
@@ -134,39 +134,39 @@
                };
        };
 
-       spi3_default: spi3_default {
-               pinmux {
-                       function = "blsp_spi3";
-                       pins = "gpio8", "gpio9", "gpio11";
-               };
-               pinmux_cs {
-                       function = "gpio";
-                       pins = "gpio10";
-               };
-               pinconf {
-                       pins = "gpio8", "gpio9", "gpio11";
-                       drive-strength = <12>;
-                       bias-disable;
-               };
-               pinconf_cs {
-                       pins = "gpio10";
-                       drive-strength = <16>;
-                       bias-disable;
-                       output-high;
-               };
-       };
-
-       spi3_sleep: spi3_sleep {
-               pinmux {
-                       function = "gpio";
-                       pins = "gpio8", "gpio9", "gpio10", "gpio11";
-               };
-               pinconf {
-                       pins = "gpio8", "gpio9", "gpio10", "gpio11";
-                       drive-strength = <2>;
-                       bias-pull-down;
-               };
-       };
+       // spi3_default: spi3_default {
+       //      pinmux {
+       //              function = "blsp_spi3";
+       //              pins = "gpio8", "gpio9", "gpio11";
+       //      };
+       //      pinmux_cs {
+       //              function = "gpio";
+       //              pins = "gpio10";
+       //      };
+       //      pinconf {
+       //              pins = "gpio8", "gpio9", "gpio11";
+       //              drive-strength = <12>;
+       //              bias-disable;
+       //      };
+       //      pinconf_cs {
+       //              pins = "gpio10";
+       //              drive-strength = <16>;
+       //              bias-disable;
+       //              output-high;
+       //      };
+       // };
+
+       // spi3_sleep: spi3_sleep {
+       //      pinmux {
+       //              function = "gpio";
+       //              pins = "gpio8", "gpio9", "gpio10", "gpio11";
+       //      };
+       //      pinconf {
+       //              pins = "gpio8", "gpio9", "gpio10", "gpio11";
+       //              drive-strength = <2>;
+       //              bias-pull-down;
+       //      };
+       // };

Note: I commented out the spi3 configuration just in case it would clash with gpio setup (as they both use gpio11). I realise spi3 is disabled by default, but it wasn’t working before I commented this out either so I just tried it.

I build the device tree based on the documentation at 96boards and use fastboot to flash the new boot-db410.img

I am attempting to test the GPIO funcionality following these instructions (using sysfs)
ie.

cd /sys/class/gpio
echo 11 > export
cd gpio11
cat direction //'in' by default
echo out > direction
cat value //'0' by default
echo 1 > value

While doing this I am measuring the appropriate pin with an oscilloscope, but the voltage remains at 1.8V the entire time.

As a side note, I noticed the dragonboard 410 documentation mentions the some pins are set as GPIOs by default DragonBoard410c: 36, 12, 13, 69, 115, 4, 24, 25, 35, 34, 28, 33. I am unable to find where/how these may be set up in the device tree though…

Any help here would be appreciated… potentially relating to mistakes in my device tree configuration, and also on how I can verify my changes are taking effect when the board has booted.

All you need to do is disabling the device node which uses these pins (blsp_spi3), then there is no need to specifidy anything else in the DTS, all ‘non-configured’ pins will be available as GPIO by default. Also note that the GPIO number you get in /sys/class/gpio is a global GPIO index, meaning that it not necessarily matches the one you expect. I suggest to look at:

For better control, I also suggest to use gpiod tool (e.g. gpioset gpiochip0 11=1)

check the gpio 11 defined elsewhere. set gpio 11 as gpio i/o in the dts, sometimes if it is defined as non i/o either in aboot/xbl/tz, it may not work as gpio i/o.

overriding in dts as gpio i/o in dts will work, iff it has permission enabled in tz.

status = “disabled”; is enough, we do not have to remove spi3_*

regards,
vinaysimha

Hi, thanks for the feedback. Certainly looks like gpiod is easier/clearer to use.
The only issue I’m having now is that using gpiod still doesn’t seem to set the gpios properly.

I tried the following (for GPIO11 in this example):

Note, on boot GPIO11 sits at 1.8V

root@linaro-alip:/home/linaro# gpioinfo
gpiochip0 - 122 lines:
        line   0:      unnamed       unused   input  active-high 
        line   1:      unnamed       unused   input  active-high 
        line   2:      unnamed       unused   input  active-high 
        line   3:      unnamed       unused   input  active-high 
        line   4:      unnamed       unused  output  active-high 
        line   5:      unnamed       unused  output  active-high 
        line   6:      unnamed       unused   input  active-high 
        line   7:      unnamed       unused   input  active-high 
        line   8:      unnamed       unused   input  active-high 
        line   9:      unnamed       unused   input  active-high 
        line  10:      unnamed       unused   input  active-high 
        line  11:      unnamed       unused   input  active-high 
        line  12:      unnamed       unused   input  active-high 
        line  13:      unnamed       unused   input  active-high 
        line  14:      unnamed       unused   input  active-high 
        line  15:      unnamed       unused   input  active-high 
        line  16:      unnamed       unused   input  active-high 
        line  17:      unnamed       unused   input  active-high 
        line  18:      unnamed       unused   input  active-high 
        line  19:      unnamed       unused   input  active-high 
        line  20:      unnamed       unused   input  active-high 
        line  21:      unnamed "apq8016-sbc:green:user1" output active-high [used]
        line  22:      unnamed       unused   input  active-high 
        line  23:      unnamed       unused   input  active-high 
        line  24:      unnamed       unused   input  active-high 
        line  25:      unnamed       unused   input  active-high 
        line  26:      unnamed       unused   input  active-high 
        line  27:      unnamed       unused   input  active-high 
        line  28:      unnamed       unused   input  active-high 
        line  29:      unnamed       unused   input  active-high 
        line  30:      unnamed       unused   input  active-high 
        line  31:      unnamed       unused   input  active-high 
        line  32:      unnamed       unused   input  active-high 
        line  33:      unnamed       unused   input  active-high 
        line  34:      unnamed       unused   input  active-high 
        line  35:      unnamed       unused   input  active-high 
        line  36:      unnamed       unused   input  active-high 
        line  37:      unnamed       unused   input  active-high 
        line  38:      unnamed         "cd"   input   active-low [used]
        line  39:      unnamed       unused   input  active-high 
        line  40:      unnamed       unused   input  active-high 
        line  41:      unnamed       unused   input  active-high 
        line  42:      unnamed       unused   input  active-high 
        line  43:      unnamed       unused   input  active-high 
        line  44:      unnamed       unused   input  active-high 
        line  45:      unnamed       unused   input  active-high 
        line  46:      unnamed       unused   input  active-high 
        line  47:      unnamed       unused   input  active-high 
        line  48:      unnamed       unused   input  active-high 
        line  49:      unnamed       unused   input  active-high 
        line  50:      unnamed       unused   input  active-high 
        line  51:      unnamed       unused   input  active-high 
        line  52:      unnamed       unused   input  active-high 
        line  53:      unnamed       unused   input  active-high 
        line  54:      unnamed       unused   input  active-high 
        line  55:      unnamed       unused   input  active-high 
        line  56:      unnamed       unused   input  active-high 
        line  57:      unnamed       unused   input  active-high 
        line  58:      unnamed       unused   input  active-high 
        line  59:      unnamed       unused   input  active-high 
        line  60:      unnamed       unused   input  active-high 
        line  61:      unnamed       unused   input  active-high 
        line  62:      unnamed       unused   input  active-high 
        line  63:      unnamed       unused   input  active-high 
        line  64:      unnamed       unused   input  active-high 
        line  65:      unnamed       unused   input  active-high 
        line  66:      unnamed       unused   input  active-high 
        line  67:      unnamed       unused   input  active-high 
        line  68:      unnamed       unused   input  active-high 
        line  69:      unnamed       unused   input  active-high 
        line  70:      unnamed       unused   input  active-high 
        line  71:      unnamed       unused   input  active-high 
        line  72:      unnamed       unused   input  active-high 
        line  73:      unnamed       unused   input  active-high 
        line  74:      unnamed       unused   input  active-high 
        line  75:      unnamed       unused   input  active-high 
        line  76:      unnamed       unused   input  active-high 
        line  77:      unnamed       unused   input  active-high 
        line  78:      unnamed       unused   input  active-high 
        line  79:      unnamed       unused   input  active-high 
        line  80:      unnamed       unused   input  active-high 
        line  81:      unnamed       unused   input  active-high 
        line  82:      unnamed       unused   input  active-high 
        line  83:      unnamed       unused   input  active-high 
        line  84:      unnamed       unused   input  active-high 
        line  85:      unnamed       unused   input  active-high 
        line  86:      unnamed       unused   input  active-high 
        line  87:      unnamed       unused   input  active-high 
        line  88:      unnamed       unused   input  active-high 
        line  89:      unnamed       unused   input  active-high 
        line  90:      unnamed       unused   input  active-high 
        line  91:      unnamed       unused   input  active-high 
        line  92:      unnamed       unused   input  active-high 
        line  93:      unnamed       unused   input  active-high 
        line  94:      unnamed       unused   input  active-high 
        line  95:      unnamed       unused   input  active-high 
        line  96:      unnamed       unused   input  active-high 
        line  97:      unnamed       unused   input  active-high 
        line  98:      unnamed       unused   input  active-high 
        line  99:      unnamed       unused   input  active-high 
        line 100:      unnamed       unused   input  active-high 
        line 101:      unnamed       unused   input  active-high 
        line 102:      unnamed       unused   input  active-high 
        line 103:      unnamed       unused   input  active-high 
        line 104:      unnamed       unused   input  active-high 
        line 105:      unnamed       unused   input  active-high 
        line 106:      unnamed       unused   input  active-high 
        line 107:      unnamed  "Volume Up"   input   active-low [used]
        line 108:      unnamed       unused   input  active-high 
        line 109:      unnamed       unused   input  active-high 
        line 110:      unnamed       unused   input  active-high 
        line 111:      unnamed       unused   input  active-high 
        line 112:      unnamed       unused   input  active-high 
        line 113:      unnamed       unused   input  active-high 
        line 114:      unnamed       unused   input  active-high 
        line 115:      unnamed       unused   input  active-high 
        line 116:      unnamed       unused   input  active-high 
        line 117:      unnamed       unused   input  active-high 
        line 118:      unnamed       unused   input  active-high 
        line 119:      unnamed       unused   input  active-high 
        line 120:      unnamed "apq8016-sbc:green:user2" output active-high [used]
        line 121:      unnamed         "id"   input  active-high [used]
gpiochip1 - 4 lines:
        line   0:      unnamed "apq8016-sbc:green:user3" output active-high [used]
        line   1:      unnamed "apq8016-sbc:green:user4" output active-high [used]
        line   2:      unnamed "usb3503 reset" output active-high [used]
        line   3:      unnamed       unused   input  active-high 
gpiochip2 - 4 lines:
        line   0:      unnamed       unused   input  active-high 
        line   1:      unnamed "apq8016-sbc:yellow:wlan" output active-high [used]
        line   2:      unnamed "apq8016-sbc:blue:bt" output active-high [used]
        line   3:      unnamed       unused   input  active-high 

root@linaro-alip:/home/linaro# gpioset gpiochip0 11=1

root@linaro-alip:/home/linaro# gpioinfo
gpiochip0 - 122 lines:
        line   0:      unnamed       unused   input  active-high 
        line   1:      unnamed       unused   input  active-high 
        line   2:      unnamed       unused   input  active-high 
        line   3:      unnamed       unused   input  active-high 
        line   4:      unnamed       unused  output  active-high 
        line   5:      unnamed       unused  output  active-high 
        line   6:      unnamed       unused   input  active-high 
        line   7:      unnamed       unused   input  active-high 
        line   8:      unnamed       unused   input  active-high 
        line   9:      unnamed       unused   input  active-high 
        line  10:      unnamed       unused   input  active-high 
        line  11:      unnamed       unused  output  active-high 
        line  12:      unnamed       unused   input  active-high 
        line  13:      unnamed       unused   input  active-high 
        line  14:      unnamed       unused   input  active-high 
        line  15:      unnamed       unused   input  active-high 
        line  16:      unnamed       unused   input  active-high 
        line  17:      unnamed       unused   input  active-high 
        line  18:      unnamed       unused   input  active-high 
        line  19:      unnamed       unused   input  active-high 
        line  20:      unnamed       unused   input  active-high 
        line  21:      unnamed "apq8016-sbc:green:user1" output active-high [used]
        line  22:      unnamed       unused   input  active-high 
        line  23:      unnamed       unused   input  active-high 
        line  24:      unnamed       unused   input  active-high 
        line  25:      unnamed       unused   input  active-high 
        line  26:      unnamed       unused   input  active-high 
        line  27:      unnamed       unused   input  active-high 
        line  28:      unnamed       unused   input  active-high 
        line  29:      unnamed       unused   input  active-high 
        line  30:      unnamed       unused   input  active-high 
        line  31:      unnamed       unused   input  active-high 
        line  32:      unnamed       unused   input  active-high 
        line  33:      unnamed       unused   input  active-high 
        line  34:      unnamed       unused   input  active-high 
        line  35:      unnamed       unused   input  active-high 
        line  36:      unnamed       unused   input  active-high 
        line  37:      unnamed       unused   input  active-high 
        line  38:      unnamed         "cd"   input   active-low [used]
        line  39:      unnamed       unused   input  active-high 
        line  40:      unnamed       unused   input  active-high 
        line  41:      unnamed       unused   input  active-high 
        line  42:      unnamed       unused   input  active-high 
        line  43:      unnamed       unused   input  active-high 
        line  44:      unnamed       unused   input  active-high 
        line  45:      unnamed       unused   input  active-high 
        line  46:      unnamed       unused   input  active-high 
        line  47:      unnamed       unused   input  active-high 
        line  48:      unnamed       unused   input  active-high 
        line  49:      unnamed       unused   input  active-high 
        line  50:      unnamed       unused   input  active-high 
        line  51:      unnamed       unused   input  active-high 
        line  52:      unnamed       unused   input  active-high 
        line  53:      unnamed       unused   input  active-high 
        line  54:      unnamed       unused   input  active-high 
        line  55:      unnamed       unused   input  active-high 
        line  56:      unnamed       unused   input  active-high 
        line  57:      unnamed       unused   input  active-high 
        line  58:      unnamed       unused   input  active-high 
        line  59:      unnamed       unused   input  active-high 
        line  60:      unnamed       unused   input  active-high 
        line  61:      unnamed       unused   input  active-high 
        line  62:      unnamed       unused   input  active-high 
        line  63:      unnamed       unused   input  active-high 
        line  64:      unnamed       unused   input  active-high 
        line  65:      unnamed       unused   input  active-high 
        line  66:      unnamed       unused   input  active-high 
        line  67:      unnamed       unused   input  active-high 
        line  68:      unnamed       unused   input  active-high 
        line  69:      unnamed       unused   input  active-high 
        line  70:      unnamed       unused   input  active-high 
        line  71:      unnamed       unused   input  active-high 
        line  72:      unnamed       unused   input  active-high 
        line  73:      unnamed       unused   input  active-high 
        line  74:      unnamed       unused   input  active-high 
        line  75:      unnamed       unused   input  active-high 
        line  76:      unnamed       unused   input  active-high 
        line  77:      unnamed       unused   input  active-high 
        line  78:      unnamed       unused   input  active-high 
        line  79:      unnamed       unused   input  active-high 
        line  80:      unnamed       unused   input  active-high 
        line  81:      unnamed       unused   input  active-high 
        line  82:      unnamed       unused   input  active-high 
        line  83:      unnamed       unused   input  active-high 
        line  84:      unnamed       unused   input  active-high 
        line  85:      unnamed       unused   input  active-high 
        line  86:      unnamed       unused   input  active-high 
        line  87:      unnamed       unused   input  active-high 
        line  88:      unnamed       unused   input  active-high 
        line  89:      unnamed       unused   input  active-high 
        line  90:      unnamed       unused   input  active-high 
        line  91:      unnamed       unused   input  active-high 
        line  92:      unnamed       unused   input  active-high 
        line  93:      unnamed       unused   input  active-high 
        line  94:      unnamed       unused   input  active-high 
        line  95:      unnamed       unused   input  active-high 
        line  96:      unnamed       unused   input  active-high 
        line  97:      unnamed       unused   input  active-high 
        line  98:      unnamed       unused   input  active-high 
        line  99:      unnamed       unused   input  active-high 
        line 100:      unnamed       unused   input  active-high 
        line 101:      unnamed       unused   input  active-high 
        line 102:      unnamed       unused   input  active-high 
        line 103:      unnamed       unused   input  active-high 
        line 104:      unnamed       unused   input  active-high 
        line 105:      unnamed       unused   input  active-high 
        line 106:      unnamed       unused   input  active-high 
        line 107:      unnamed  "Volume Up"   input   active-low [used]
        line 108:      unnamed       unused   input  active-high 
        line 109:      unnamed       unused   input  active-high 
        line 110:      unnamed       unused   input  active-high 
        line 111:      unnamed       unused   input  active-high 
        line 112:      unnamed       unused   input  active-high 
        line 113:      unnamed       unused   input  active-high 
        line 114:      unnamed       unused   input  active-high 
        line 115:      unnamed       unused   input  active-high 
        line 116:      unnamed       unused   input  active-high 
        line 117:      unnamed       unused   input  active-high 
        line 118:      unnamed       unused   input  active-high 
        line 119:      unnamed       unused   input  active-high 
        line 120:      unnamed "apq8016-sbc:green:user2" output active-high [used]
        line 121:      unnamed         "id"   input  active-high [used]
gpiochip1 - 4 lines:
        line   0:      unnamed "apq8016-sbc:green:user3" output active-high [used]
        line   1:      unnamed "apq8016-sbc:green:user4" output active-high [used]
        line   2:      unnamed "usb3503 reset" output active-high [used]
        line   3:      unnamed       unused   input  active-high 
gpiochip2 - 4 lines:
        line   0:      unnamed       unused   input  active-high 
        line   1:      unnamed "apq8016-sbc:yellow:wlan" output active-high [used]
        line   2:      unnamed "apq8016-sbc:blue:bt" output active-high [used]
        line   3:      unnamed       unused   input  active-high 

Note: GPIO11 changed to output

root@linaro-alip:/home/linaro# gpioget gpiochip0 11
0

root@linaro-alip:/home/linaro# gpioset gpiochip0 11=0

root@linaro-alip:/home/linaro# gpioget gpiochip0 11
0

So it looks like GPIO11 gets set to an output, but the value never changes. Note, the voltage on the pin also stays at 1.8V the entire time.

I also tried the same as above with GPIO36 and had the same result, other than that the voltage on that pin is always at 0V.

Can you see anything I am missing in my setup, or usage of gpiod?

Thanks

Not all GPIOs can be changed by the Applications processor (APPs), some GPIOs are assigned ownership to other processors (for example the QDSP). The listing of GPIO assignments are here: https://developer.qualcomm.com/qfile/28814/lm80-p0436-6_gpio_pin_assignment.pdf

In the case of GPIO-11 and GPIO-31 you should be able to modify them if you have appropriate permissions.

I have never seen the use of the // comment operator in a device tree file, but it is supposed to work https://stackoverflow.com/questions/21871362/how-to-put-comments-in-device-tree-source-files