Kernel中GPIO的Sysfs接口的使用

今天想写一个gpio的驱动,用于控制SoC上的一个电源控制io。看了一会儿,觉得对于gpio这种标准设备,kernel中应该有通用的驱动,甚至应该有Sysfs的接口可供用户空间程序使用。
于是先看了下driver目录,发现果然有gpio这个目录,不过里面的东西太多,一时没有头绪。又想起Documents目录,找到一个gpio.txt,果然Kernel提供了一个gpiolib的模块,用于向用户空间提供控制接口,使用上在这里简单做个说明:
1. 打开gpiolib支持,在menuconfig中,
Device Drivers->GPIO Support,选择:
[*] /sys/class/gpio/… (sysfs interface)
<*> Generic memory-mapped GPIO controller support (MMIO platform device)
2. 加载新的kernel之后,在/sys/class/下,多出gpio这个目录,其中有export与unexport俩个文件,输入echo N > /sys/class/gpio/export,则该目录下会再出现以gpioN为名字的目录,这就是我们要控制的gpio的映射,可以控制其方向、高低及触发方式。N是由n*32 + m得来,n是第n个gpio模块,m是寄存器第m位。
3. 不过,对于已经被系统分配的GPIO,echo操作会失败,这是一种保护机制,为了测试,可以修改下代码来屏蔽(3.10.35内核):

1393 static int gpiod_request(struct gpio_desc *desc, const char *label)
1394 {
1395     struct gpio_chip    *chip;
1396     int         status = -EPROBE_DEFER;
1397     unsigned long       flags;
...
1410     if (!try_module_get(chip->owner))
1411         goto done;
1412
1413     /* NOTE:  gpio_request() can be called in early boot,
1414      * before IRQs are enabled, for non-sleeping (SOC) GPIOs.
1415      */
1416
1417     desc->flags =   0;//重置flags值,仅供测试
1418     if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
1419         desc_set_label(desc, label ? : "?");
1420         status = 0;
1421     } else {
1422         status = -EBUSY;
1423         module_put(chip->owner);
1424         goto done;
1425     }
...
1452 }

至此,我们就可以在user space中,操作gpio了。

你可能感兴趣的:(linux,GPIO)