转
最近在玩友善之臂Tiny6410开发板,但是源码中没有用户层操作GPIO的GPIO驱动,且之前的工作一直都是看和改,难免手生,故写此GPIO驱动,以作练习之用。
1. 驱动层gpio.c
编译:将此gpio.c放在driver/gpio目录下,并修改下面的Makefile文件,添加 obj-y += gpio.o
使用此驱动在命令行下操作GPIO:
cd /sys/class/s3c-gpio
echo GPK 4 0 > write // 设置GPK4输出0
echo GPN 0 > read //读取GPN0的状态
关闭/打开 GPIO驱动调试信息:
cd /sys/module/gpio/parameters
echo 0 > gpio_dbg //关闭GPIO驱动调试信息
echo 1 > gpio+dbg //打开GPIO驱动调试信息
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>
static int gpio_dbg = 1;
module_param(gpio_dbg, int, S_IRUGO | S_IWUSR);
#define gpio_dbg(format, args...) \
do { \
if(gpio_dbg) \
printk(format, ##args); \
} while (0)
#define CLASS_NAME "s3c-gpio"
static struct class *gpio_class;
static int s3c64xx_gpio_sections[] = {
S3C64XX_GPA(0), S3C64XX_GPB(0), S3C64XX_GPC(0), S3C64XX_GPD(0),
S3C64XX_GPE(0), S3C64XX_GPF(0), S3C64XX_GPG(0), S3C64XX_GPH(0),
S3C64XX_GPI(0), S3C64XX_GPJ(0), S3C64XX_GPK(0), S3C64XX_GPL(0),
S3C64XX_GPM(0), S3C64XX_GPN(0), S3C64XX_GPO(0), S3C64XX_GPP(0),
S3C64XX_GPQ(0),
};
static int s3c_gpio_get_pin_nr(char* label, int nr)
{
struct s3c_gpio_chip *chip;
int pin;
int ret = -EINVAL;
int i;
for(i=0; i<ARRAY_SIZE(s3c64xx_gpio_sections); i++)
{
pin = s3c64xx_gpio_sections[i];
chip = s3c_gpiolib_getchip(pin);
if (!chip)
continue;
if(strcmp(chip->chip.label, label)==0)
{
if(nr<(chip->chip.ngpio))
{
pin = pin + nr;
ret = pin;
}
break;
}
}
if(ret<0)
printk("Can't find gpio: [%s%d] !\n", label, nr);
else
gpio_dbg("Find gpio: [%s%d], nr = %d\n", label, nr, ret);
return ret;
}
static ssize_t gpio_read_show(struct class *dev, struct class_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", "Usage: echo GPX nr > read");
}