linux gpio驱动示例

#include <linux/fs.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <gpio.h>
#include <soc/gpio.h>

#define JT_GPIO_MAGIC ('k')
#define JT_GPIO_READ _IO(JT_GPIO_MAGIC, 1)
#define JT_GPIO_WRITE _IO(JT_GPIO_MAGIC, 2)
#define WAKEUP_PIN GPIO_PB(28)

MODULE_AUTHOR("Bing <[email protected]>");
MODULE_DESCRIPTION("JT WAKEUP  GPIO Pin Driver");
MODULE_LICENSE("GPL");

static int major;
static struct class *jt_gpio_class;
static struct device *jt_gpio_device;

static int jt_gpio_open(struct inode *inode, struct file *file)
{
	return 0;
}

static int jt_gpio_release(struct inode *inode, struct file *file)
{
	return 0;
}

static long jt_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	int value;
	get_user(value, (int *)arg);
	switch (cmd) {
	case JT_GPIO_WRITE:
		gpio_set_value(WAKEUP_PIN, value);
		break;
	default:
		printk(KERN_INFO "unsupported cmd\n");
		return -1;
	}

	return 0;
}

const struct file_operations jt_gpio_fops = {
	.owner = THIS_MODULE,
	.open  = jt_gpio_open,
	.release = jt_gpio_release,
	.unlocked_ioctl = jt_gpio_ioctl,
};

static int __init jt_gpio_init(void)
{
	int ret;
	ret =  gpio_request_one(WAKEUP_PIN, GPIOF_DIR_OUT, "JT_WAKEUP");
	if (ret) {
		printk(KERN_INFO "gpio_request  wakeup pin fail\n");
		return -1;
	}
	ret =  gpio_direction_output(WAKEUP_PIN, 0);
	if (ret) {
		printk(KERN_INFO "gpio as output pin fail\n");
		return -1;
	}
	major = register_chrdev(0, "jt_gpio", &jt_gpio_fops);
	jt_gpio_class = class_create(THIS_MODULE, "jt_gpio_class");
	if (!jt_gpio_class) {
		printk(KERN_INFO "jt_gpio class_create fail\n");
		return -1;
	}
	jt_gpio_device = device_create(jt_gpio_class, NULL, MKDEV(major, 0), NULL, "jt_gpio");
	if (!jt_gpio_device) {
		printk(KERN_INFO "jt_gpio device_create fail\n");
		return -1;
	}
	return 0;
}

static void __exit jt_gpio_exit(void)
{
	gpio_free(WAKEUP_PIN);
	unregister_chrdev(major, "jt_gpio");
	device_unregister(jt_gpio_device);
	class_destroy(jt_gpio_class);

}
module_init(jt_gpio_init);
module_exit(jt_gpio_exit);
内核关于gpio驱动有标准接口,一般是申请gpio,设置gpio是输入还是输出,接着设置gpio的值,使用结束撤销申请

本例将gpio注册为一个字符设备,并将其信息导出到sys文件系统,这样当系统启动udev后会自动创建设备节点,
从而省去手动创建的麻烦.

下面是应用测试程序:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>

#define HELLO_MAGIC 'k'
#define GPIO_READ _IO (HELLO_MAGIC, 1)
#define GPIO_WRITE _IO (HELLO_MAGIC, 2)

int main(int argc, char** argv)
{
	int fd;
	int ret = 0;
	int value = 0;
	if (argc != 2) {
		printf("usage : ./a.out value\n");
		exit(-1);
	}

	value = atoi(argv[1]);

	fd = open("/dev/jt_gpio",O_RDWR);
	if (fd < 0) {
		printf ("open wakup gpio fail\n");
		return -1;
	}

	ret = ioctl (fd, GPIO_WRITE,&value);
	if (ret < 0) {
		close(fd);
		printf("set wakeup pin to %d fail \n", value);
		return -1;
	}

	close (fd);
	return 0;
}

发布了31 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Hsu_smile/article/details/51026882