How to manage SW3 button from application

I am trying to program the SW3 switch on the Carrier Ixora 1.2a / imx6 board. The switch is connected by default to pin 186 (which in turn is connected to GPIO1.IO15) because the resistor R91 is mounted and R90 is not.
I configured the pin for the GPIO function:

//SW3 button
//GPIO1_IO15 = [(x-1)*32]+y = [(1-1)*32]+15 = 15
fd = open(“/sys/class/gpio/export”, O_WRONLY); write(fd, “15”, 2); close(fd);
fd = open(“/sys/class/gpio/gpio15/direction”, O_WRONLY); write(fd, “in”, 2); close(fd);

Using the read function:

int GPIO_SW3(void)
{
char value;
int file;
file = open(“/sys/class/gpio/gpio15/value”, O_RDONLY);
read(file, &value, 1); // read GPIO value
close(file); //close value file
if(value==‘0’) return 1; //signal denied
return 0;
}

But I always read SW3 = 0 even if it is pressed.

Is there something I’m doing wrong? Do I need to do something else?

Thanks

Hi, I’m the Toradex AI Assistant.

I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.

Did you like my answer? :+1: :-1:


Hello! Thank you for your detailed explanation. You’re on the right track with configuring GPIO1_IO15. However, there are a few important points to consider that may be affecting your results on the Ixora Carrier Board.

1. Verify GPIO Calculation

Your calculation is correct:

  • GPIO1_IO15 = [(1-1)*32]+15 = 15
    So, GPIO 15 in sysfs is correct.

2. Pinmux Verification

Ensure that the pinmux configuration in your device tree or boot configuration really sets pin 186 (GPIO1_IO15) for GPIO functionality, not for another peripheral. This is especially important if you are using a custom device tree or a recent BSP.

3. Electrical State and Resistors

By default, the SW3 switch connects to pin 186 via R91. When the button is pressed, it typically pulls the signal low, otherwise, it is high. If there is no external pull-up resistor and no internal pull-up configured, the input could “float” and always read low (0). Please verify if the SoC pin has an internal pull-up enabled or check if the carrier board provides the necessary pullup (Info).

4. Use of Modern GPIO Interface

Instead of sysfs, consider using the modern libgpiod approach, since sysfs is deprecated on recent Linux kernels. Here is a simple example to read the state of your GPIO using gpiod tools:

# Find your gpiochip
gpiodetect

# List lines of the relevant chip, e.g., gpiochip0
gpioget gpiochip0 15

Or programmatically in C:

#include <gpiod.h>
struct gpiod_chip *chip = gpiod_chip_open_by_name("gpiochip0");
struct gpiod_line *line = gpiod_chip_get_line(chip, 15);
gpiod_line_request_input(line, "sw3reader");
int val = gpiod_line_get_value(line);

Sample reference

5. Additional Troubleshooting Steps

  • While SW3 is not pressed, check the voltage on the pin with a multimeter to ensure it’s high by default and goes low when pressed.
  • Double-check /sys/class/gpio/gpio15/value while toggling the switch (using cat /sys/class/gpio/gpio15/value in a separate terminal).
  • Ensure there are no conflicting drivers or devices controlling that GPIO.

Would you like specific guidance using the libgpiod API or CLI? This will future-proof your application and may resolve your issue.

Best regards,
Toradex AI Assistant.
Ixora Carrier Board Info
libgpiod Example Blog

thank you so much for the quick reply.
But now my problem is how to verify that the Pinmux configuration in the device tree is correct?
I don’t have much experience on the subject.

thanks

typing
cat /sys/kernel/debug/pinctrl/pinctrl-handles:
I saw that pin 186 is set MX6Q_PAD_NANDF_CS1 but is it correct? How do I make it GPIO?
Thank you

here is the result:
Requested pin control handlers their pinmux maps:
device: 20e0000.iomuxc current state: default
state: default
type: MUX_GROUP controller 20e0000.iomuxc group: gpio2io04grp (0) function: iomuxc (0)
type: CONFIGS_PIN controller 20e0000.iomuxc pin MX6Q_PAD_NANDF_D4 (195)config 000130b0
type: MUX_GROUP controller 20e0000.iomuxc group: gpio2io05grp (1) function: iomuxc (0)
type: CONFIGS_PIN controller

state: default
type: MUX_GROUP controller 20e0000.iomuxc group: usdhc2grp (55) function: iomuxc (0)
type: CONFIGS_PIN controller 20e0000.iomuxc pin MX6Q_PAD_SD2_CMD (214)config 00017071
type: CONFIGS_PIN controller 20e0000.iomuxc pin MX6Q_PAD_SD2_CLK (213)config 00010071
type: CONFIGS_PIN controller 20e0000.iomuxc pin MX6Q_PAD_SD2_DAT0 (21)config 00017071
type: CONFIGS_PIN controller 20e0000.iomuxc pin MX6Q_PAD_SD2_DAT1 (19)config 00017071
type: CONFIGS_PIN controller 20e0000.iomuxc pin MX6Q_PAD_SD2_DAT2 (20)config 00017071
type: CONFIGS_PIN controller 20e0000.iomuxc pin MX6Q_PAD_SD2_DAT3 (215)config 00017071
type: MUX_GROUP controller 20e0000.iomuxc group: gpiosdcdgrp (40) function: iomuxc (0)
type: CONFIGS_PIN controller 20e0000.iomuxc pin MX6Q_PAD_NANDF_CS1 (186)config 000000b0
device: 2198000.usdhc current state: default
state: default
type: MUX_GROUP controller 20e0000.iomuxc group: usdhc3grp (56) function: iomuxc (0)
type: CONFIGS_PIN controller 20e0000.iomuxc pin MX6Q_PAD_SD3_CMD (174)config 00017059
type: CONFIGS_PIN controller 20e0000.iomuxc pin MX6Q_PAD_SD3_CLK (175)config 00010059
type: CONFIGS_PIN controller 20e0000.iomuxc pin MX6Q_PAD_SD3_DAT0 (176)config 00017059

Hey @CLA1965,

We apologize for the delayed response. I assume you are using one of our reference images (not Torizon), from how you are reading the GPIO values, is that correct?

Since the SW3 switch is used for recovery, we don’t recommend using it for custom functionality, even if it is possible. Does your application require the usage of this switch? Can you use one of the exposed GPIO pins on the X27 header?

Even if you need to use the SW3 switch, can you successfully read the GPIO values of other pins when connecting an external switch? I’ll also be investigating from here.

Best regards,

Hey, @CLA1965,

I investigated a bit further and found some more details relevant to your use case.

In the upstream kernel (arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi), the following group sets the 186 pin for the SDIO interface usage:

	pinctrl_usdhc2: usdhc2grp {
		fsl,pins = <
			MX6QDL_PAD_SD2_CMD__SD2_CMD    0x17071
			MX6QDL_PAD_SD2_CLK__SD2_CLK    0x10071
			MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17071
			MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17071
			MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17071
			MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17071
		>;
	};

And it is activated in the imx6q-apalis-eval.dts device tree, as shown below:

/* SD1 */
&usdhc2 {
	cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_usdhc2 &pinctrl_sd_cd>;
	status = "okay";
};

Since the pin is not being used as GPIO, you will not be able to read its value via the GPIO interface as you are doing.

Once again, we do not recommend using the 186 pin for custom functionality, but if your project demands it and there is no other alternative, you can write a device tree overlay to enable the pin’s GPIO functionality. Keep in mind that to change this pin’s functionality, you will have to disable the entire SDIO interface.

I hope this helps clarifying things up.

Best regards,