imx6ull , GPIO with SION set to ON but gpio_get_value still always return 0

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

imx6ull , GPIO with SION set to ON but gpio_get_value still always return 0

1,789 Views
candy
Contributor I

Hello, all! I'm using imx6ull GPIO1_IO03 to drive a LED, and I have configd the pin in the device tree. It is ok to turn on and turn off LED, that means gpio_set_value() works well. But when I use gpio_get_value() to read the pin to toggle the LED, it always return 0.Then I try to set the bit 30 of the config register, what's in your word, SION bit as 1, unfortunately, it still does not work.

Below is the LED part configuration in the device tree

 

&iomuxc {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_hog_1>;
	imx6ul-evk {
		pinctrl_alpha_led0: alpha-led0 {
			fsl,pins = <
			    MX6UL_PAD_GPIO1_IO03__GPIO1_IO03  0x400010b0	
			>;
		};

		pinctrl_alpha_led1: alpha-led1 {
			fsl,pins = <
		            MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01  0x400010b0
			>;
		};

	    /* some other nodes */
	};

	/* some other nodes */
};


/ {
	/* some other nodes */

	alpha-leds {
		compatible = "alientek-alpha,leds";

		led-0 {
			pinctrl-names = "default";
			pinctrl-0 = <&pinctrl_alpha_led0>;
			gpio = <&gpio1 3 GPIO_ACTIVE_HIGH>;
			status = "okay";
		};

		led-1 {
			pinctrl-names = "default";
			pinctrl-0 = <&pinctrl_alpha_led1>;
			gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>;
			status = "okay";
		};
	};

	/* some other nodes */
};

 

What's may be the problem of this , why gpio_get_value dose not return pin value correctly? How can I fix this?

Tags (1)
0 Kudos
Reply
6 Replies

1,754 Views
AldoG
NXP TechSupport
NXP TechSupport

Hello,

it is indeed the correct way to set the bit 30 for SION, so this configuration should not have a problem.

I believe you’re using a custom board and not an EVK, have you tried manually driving the GPIO and check if the status change?

Also, since you have only shared the portion of the dts where the GPIO is defined, have you looked if this pad has not been used by another peripheral?

Best regards,
Aldo.

0 Kudos
Reply

1,749 Views
candy
Contributor I

Yes, I have checked the usage of the pins, they are not used anywhere else. And I can turn on and turn off the led by using gpio_set_value.  After few days of debugging, I found that the mux register value and config register value I set in the device-tree were not written to the corresponding registers. I read out the mux register and found that it was just the value same as default, not what I set in the pinctrl node.

Maybe there was an important point I was missing,: I'm using the pure chrdev driver, not platrom driver model.  I thought gpio subsystem would call pinctrl subsystem to set mux register, but it seemed not working the way as I thought. Below is my test code:

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/ide.h>


#define REG_MUX_GPIO5_IO01 	0x0229000C
static void __iomem *mux_gpio5_io01;

static int gpio;

static int __init led_init(void)
{
	const char *status;
	int ret, value;
	struct device_node *node = NULL;
	
	node = of_find_compatible_node(NULL, NULL, "alientek-alpha,leds");
	if(!node) {
		printk("error: of_find_compatible_node\n");
		return -ENODEV;
	}
	
	ret = of_property_read_string(node, "status", &status);
	if((ret != 0) || (strcmp(status, "okay") != 0)) {
		printk("error: of_property_read_string\n");
		return -ENODEV;
	}

	gpio = of_get_named_gpio(node, "gpio", 0);
	if(gpio < 0) {
		printk("error: of_get_named_gpio\n");
		return -ENODEV;
	}
	
	ret = gpio_request(gpio, "led-pin");
	if(ret) {
		printk("error: gpio_request\n");
		return -ENODEV;
	}

	ret = gpio_direction_output(gpio, 1);
	if(ret) {
		printk("error: gpio_direction_output\n");
		goto error;
	}

	value = gpio_get_value(gpio);
	printk("gpio value = %d\n", value);

	mux_gpio5_io01 = ioremap(REG_MUX_GPIO5_IO01, 4);
	if(mux_gpio5_io01) {
		value = readl(mux_gpio5_io01);
		printk("reg value = %08X\n", value);
	}
	
	return 0;

error:
	gpio_free(gpio);

	return -1;
}

static void __exit led_exit(void)
{
	int value;

	value = gpio_get_value(gpio);
	printk("gpio value = %d\n", value);

	if(mux_gpio5_io01) {
		value = readl(mux_gpio5_io01);
		printk("reg value = %08X\n", value);
	}

	gpio_free(gpio);
	if(mux_gpio5_io01) iounmap(mux_gpio5_io01);
}

module_init(led_init);
module_exit(led_exit);

MODULE_AUTHOR("David");
MODULE_LICENSE("GPL");

 

Does platform driver do a bit more work than pure chardev driver ?  eg, call pinctrl subsystem for us ?

Appreciate the help.

0 Kudos
Reply

1,719 Views
AldoG
NXP TechSupport
NXP TechSupport

Hello,

I don't know BSP version you are working with but it may be helpful to check the latest documentation available here:

https://source.codeaurora.org/external/imx/linux-imx/tree/Documentation/devicetree/bindings/gpio/gpi...

 

https://source.codeaurora.org/external/imx/linux-imx/tree/Documentation/devicetree/bindings/gpio/fsl...

 

Also, you may check the GPIO function implementation:
https://source.codeaurora.org/external/imx/linux-imx/tree/drivers/gpio/gpio-mxc.c?h=lf-5.15.y

 

Best regards,
Aldo.

0 Kudos
Reply

1,716 Views
candy
Contributor I

Thanks, it turns out only with platform driver interface, the pinctrl configuration would work.

0 Kudos
Reply

1,780 Views
candy
Contributor I

Okay, I figure out that's not gpio_get_value's problem. I print the mux register and find that the SION bit is not 1. It's still 0 even when I set config register to 0x400010b0. Wha's more , I try to directly modify the MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 macro definiton in imx6ul-pinfunc.h to add SION bit , change 0x5 to 0x15, still not work. The mux register still read out as 0x5, not 0x15. Only if I use iomap to set the mux register , SION can be set to 1 successfully. Why ? anybody knows?

0 Kudos
Reply

1,761 Views
candy
Contributor I

By the way, I use the gpio_ legacy functions , instead of gpiod_ new functions. Does it matter ? It seems that configuration datas in the pinctrl node are not written to the registers. Any ideas ?

0 Kudos
Reply