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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章