nt9856x/BSP/linux-kernel/drivers/gpio/gpioioctl.c
2023-03-28 15:07:53 +08:00

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