Control GPIO from Linux

Hello there,

I’m trying to access my GPIO.
I’m trying to set GPIO4_IO05 (iMX6 GPIO19) high.

Here is what I’m doing on the embedded linux:

# cd /sys/class/gpio
# echo 101 > export
# cd gpio101
# echo high > direction
# cat direction
out
# cat value
0

As you can see, value is still 0 (event if I put 1 in it).

I also tried to do same thing in U-Boot (I didn’t updated u-boot):

#   gpio set 101
gpio: pin 101 (gpio 101) value is 1
   Warning: value of pin is still 0

Same problem here.

I did some change on my device tree (full version here):

DTS file:

&iomuxc {
	/*
	 * Mux all pins which are unused to be GPIOs
	 * so they are ready for export to user space
	 */
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_weim_gpio_3 &pinctrl_weim_gpio_4
	             &pinctrl_weim_gpio_5 &pinctrl_weim_gpio_6
	             &pinctrl_usbh_oc_1 &pinctrl_usbc_id_1>;

	gpio {
		pinctrl_pcap_1: pcap-1 {
			fsl,pins = <
				MX6QDL_PAD_GPIO_9__GPIO1_IO09	PAD_CTRL_HYS_PD /* SODIMM 28 */
				MX6QDL_PAD_SD4_DAT2__GPIO2_IO10	PAD_CTRL_HYS_PD /* SODIMM 30 */
			>;
		};
	};
};

DTSI file:

weim {
	[...]
	/* DATA[16:31]  used as GPIO */
	pinctrl_weim_gpio_3: weim_gpio-3 {
		fsl,pins = <
			MX6QDL_PAD_EIM_LBA__GPIO2_IO27     PAD_CTRL_HYS_PU
			MX6QDL_PAD_EIM_BCLK__GPIO6_IO31    PAD_CTRL_HYS_PU
			MX6QDL_PAD_NANDF_CS3__GPIO6_IO16   PAD_CTRL_HYS_PU
			MX6QDL_PAD_NANDF_CS1__GPIO6_IO14   PAD_CTRL_HYS_PU
			MX6QDL_PAD_NANDF_RB0__GPIO6_IO10   PAD_CTRL_HYS_PU
			MX6QDL_PAD_NANDF_ALE__GPIO6_IO08   PAD_CTRL_HYS_PU
			MX6QDL_PAD_NANDF_WP_B__GPIO6_IO09  PAD_CTRL_HYS_PU
			MX6QDL_PAD_NANDF_CS0__GPIO6_IO11   PAD_CTRL_HYS_PU
			MX6QDL_PAD_NANDF_CLE__GPIO6_IO07   PAD_CTRL_HYS_PU
			MX6QDL_PAD_GPIO_19__GPIO4_IO05     PAD_CTRL_HYS_PU
			MX6QDL_PAD_CSI0_MCLK__GPIO5_IO19   PAD_CTRL_HYS_PU
			MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18 PAD_CTRL_HYS_PU
			MX6QDL_PAD_GPIO_4__GPIO1_IO04      PAD_CTRL_HYS_PU
			MX6QDL_PAD_GPIO_5__GPIO1_IO05      PAD_CTRL_HYS_PU
			MX6QDL_PAD_GPIO_2__GPIO1_IO02      PAD_CTRL_HYS_PU
		>;
	};
	[...]
};

Is there something else to make my GPIO available from Linux (I don’t really care about accessing it from UBoot)?

Thanks,

Léo

Hi

With an unchanged 2.7b3 image the commands you mention to control a GPIO work fine here both in U-Boot and in Linux. If I jumper a LED to the extension connecter pin b-10 that LED reflects whatever I command.
I also guess that it works fine on your desk.

For a GPIO configured to be output the currently commanded value can not be read back unless the SION bit is set in the pad control register. Search the community for ‘SION’.

Max

Hi Max.

I have a 2.7b3 image where I just changed the defconfig and dts file, as mentionned above.
I just tried with kernel mainline but due to many errors, I went back to Toradex’s custom branch.

As you can see, GPIO19 is not part of the gpio{} group in my device tree file. That’s maybe the issue I’m encountering.

Also, in the documentation, there is this warning:

Warning: For i.MX 6 based modules you need to make sure that the pin is actually muxed as a GPIO in the device-tree or platform data. Failing to do so will not give any error. The pin will simply report 0 if configured as an input and not react to any state change if configured as an output.

And in the Device Tree Customization guide, it is not clear which pins can be used as GPIO directly from the user space. Do I have to put the pin in &iomuxc { pinctrl-0 = XXX } or in &iomuxc { gpio { XXX } }.
Also, what does pcap refers to ?

I’m currently using my scope to see the pin state, since the SION bit problem is well marked in the documentation.

Thanks,

Léo

Hi Léo

In order to get a pin muxed one needs the pin with its configuration in dtb node which by convention has a reference name pinctrl_xxx AND then one has to add the reference to node’s pinctrl-0 property of the functionality/driver which needs these pins.

The iomuxc driver also works on its pinctrl-0 property and this can be used for pins which are not used by a particular driver, i.e. for pins which are to be used by the sysfs gpio interface.

In our device tree we group the pinctrl_xxx nodes by using function specifc nodes, e.g. the gpio node you mention. These nodes do not influence the functionality.

So GPIO_IO05 is part of the weim_gpio-3 node with reference pinctrl_weim_gpio_3 and configured to be GPIO with a pull up (and SION not set).

MX6QDL_PAD_GPIO_19__GPIO4_IO05     PAD_CTRL_HYS_PU

And that reference is added to to iomuxc’s pinctrl-0 property.

Thus the pin is muxed to be GPIO.

PCAP stands for a capacitive touch. The node you reference is likely unused in your device tree.

Max

Hi Max,

I just tried with:

  • Toradex’s DTB file
  • Toradex’s 2.7.3 u-boot version
  • Toradex’s 2.7.3 linux version
  • Toradex’s 2.7.3 rootfs

I still have exactly the same issues.

I’m using the Col iMX6S V1.0A on an old Col Eval V2.1c.
In this old evaluation board, some hardware buffers are soldered but there is no reason they make the thing not working.

I’ve triple checked that I’m correctly probing b-10 output in the expansion connector.

Thanks,

Léo

Edit: With SION bit configured, I have a correct returned value in the kernel, but still the same issue in u-boot and no physical change on the pin.
Edit2: GPIO works fine on GPIO2_IO10 (42) if I add the gpio group to iocmux as Max explained above. My problem seems to be related to the weim gpio banks

Hi Léo

So what is now the output of

devmem2 0x020E0220
devmem2 0x020E05F0

Max

FYI - PCAP is “projected” capacitance touch screen, different that capacitance touch alone. FT5x26 chip versus FT5x06 chip sets. See nice link here: www.walkermobile.com/Touch_Technologies_Tutorial_Latest_Version.pdf