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.