119 lines
3.0 KiB
C
Executable File
119 lines
3.0 KiB
C
Executable File
/**
|
|
GPIO IOCTL driver
|
|
To handle GPIO io-control driver
|
|
|
|
Copyright Novatek Microelectronics Corp. 2018. All rights reserved.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License version 2 as
|
|
published by the Free Software Foundation.
|
|
*/
|
|
#include <linux/module.h>
|
|
#include <linux/gpio.h>
|
|
#include <linux/miscdevice.h>
|
|
#include <linux/ioctl.h>
|
|
#include <linux/uaccess.h>
|
|
#include <linux/fs.h>
|
|
#define DRV_VERSION "1.00.000"
|
|
|
|
#define UNINIT_CMD_MAGIC 0xdb
|
|
#define INIT_CMD_MAGIC 0xdc
|
|
#define RESET_CMD_MAGIC 0xdd
|
|
#define GET_CMD_MAGIC 0xde
|
|
#define SET_CMD_MAGIC 0xdf
|
|
#define GET_CMD _IOWR(GET_CMD_MAGIC, 0, unsigned int)
|
|
#define SET_CMD _IOW(SET_CMD_MAGIC, 0, unsigned int)
|
|
#define INIT_CMD _IOWR(INIT_CMD_MAGIC, 0, unsigned int)
|
|
#define RESET_CMD _IOW(RESET_CMD_MAGIC, 0, unsigned int)
|
|
#define UNINIT_CMD _IOWR(UNINIT_CMD_MAGIC, 0, unsigned int)
|
|
|
|
struct gpio_ioctl_data{
|
|
int gpio_num;
|
|
int value;
|
|
};
|
|
|
|
static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|
{
|
|
struct gpio_ioctl_data val;
|
|
switch(cmd) {
|
|
case SET_CMD:
|
|
if (copy_from_user(&val, (struct gpio_ioctl_data *)arg, \
|
|
sizeof(struct gpio_ioctl_data)))
|
|
return -EFAULT;
|
|
|
|
gpio_request(val.gpio_num, "GPIOCTRL");
|
|
gpio_direction_output(val.gpio_num, val.value);
|
|
break;
|
|
case GET_CMD:
|
|
if(copy_from_user(&val, (struct gpio_ioctl_data *)arg, \
|
|
sizeof(struct gpio_ioctl_data)))
|
|
return -EFAULT;
|
|
|
|
val.value = gpio_get_value(val.gpio_num);
|
|
if(copy_to_user((struct gpio_ioctl_data *)arg, &val, \
|
|
sizeof(struct gpio_ioctl_data)))
|
|
return -EFAULT;
|
|
break;
|
|
case INIT_CMD:
|
|
if(copy_from_user(&val, (struct gpio_ioctl_data *)arg, \
|
|
sizeof(struct gpio_ioctl_data)))
|
|
return -EFAULT;
|
|
|
|
gpio_request(val.gpio_num, "GPIOCTRL");
|
|
break;
|
|
case RESET_CMD:
|
|
if (copy_from_user(&val, (struct gpio_ioctl_data *)arg, \
|
|
sizeof(struct gpio_ioctl_data)))
|
|
return -EFAULT;
|
|
|
|
gpio_direction_input(val.gpio_num);
|
|
break;
|
|
case UNINIT_CMD:
|
|
if(copy_from_user(&val, (struct gpio_ioctl_data *)arg, \
|
|
sizeof(struct gpio_ioctl_data)))
|
|
return -EFAULT;
|
|
|
|
gpio_free(val.gpio_num);
|
|
break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static const struct file_operations gpio_fops = {
|
|
.owner = THIS_MODULE,
|
|
.unlocked_ioctl = gpio_ioctl,
|
|
};
|
|
|
|
static struct miscdevice gpio_miscdev = {
|
|
.minor = MISC_DYNAMIC_MINOR,
|
|
.name = "gpio_ctrl",
|
|
.fops = &gpio_fops,
|
|
};
|
|
|
|
static int __init gpio_ctrl_init(void)
|
|
{
|
|
int ret;
|
|
|
|
ret = misc_register(&gpio_miscdev);
|
|
if (ret) {
|
|
pr_err("misc_register fail, ret = %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void __exit gpio_ctrl_dev_exit(void)
|
|
{
|
|
misc_deregister(&gpio_miscdev);
|
|
}
|
|
|
|
module_init(gpio_ctrl_init);
|
|
module_exit(gpio_ctrl_dev_exit);
|
|
|
|
MODULE_AUTHOR("Novatek Microelectronics Corp.");
|
|
MODULE_LICENSE("GPL v2");
|
|
MODULE_DESCRIPTION("GPIO IOCTL driver");
|
|
MODULE_VERSION(DRV_VERSION); |