input 驱动代码demo
时间: 2023-04-05 16:05:21 浏览: 110
以下是一个简单的 input 驱动代码示例:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/input.h>
#define DEVICE_NAME "my_input_device"
#define CLASS_NAME "my_input_class"
static struct input_dev *my_input_dev;
static struct cdev my_cdev;
static dev_t my_dev;
static struct class *my_class;
static struct device *my_device;
static int my_open(struct inode *inode, struct file *file)
{
return 0;
}
static int my_release(struct inode *inode, struct file *file)
{
return 0;
}
static ssize_t my_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
int ret;
char *data;
data = kmalloc(count, GFP_KERNEL);
if (!data)
return -ENOMEM;
ret = copy_from_user(data, buf, count);
if (ret) {
kfree(data);
return -EFAULT;
}
input_report_key(my_input_dev, KEY_A, data[0] & 1);
input_sync(my_input_dev);
kfree(data);
return count;
}
static const struct file_operations my_fops = {
.owner = THIS_MODULE,
.open = my_open,
.release = my_release,
.write = my_write,
};
static int __init my_init(void)
{
int ret;
ret = alloc_chrdev_region(&my_dev, 0, 1, DEVICE_NAME);
if (ret)
goto fail_alloc_chrdev_region;
cdev_init(&my_cdev, &my_fops);
my_cdev.owner = THIS_MODULE;
ret = cdev_add(&my_cdev, my_dev, 1);
if (ret)
goto fail_cdev_add;
my_class = class_create(THIS_MODULE, CLASS_NAME);
if (IS_ERR(my_class)) {
ret = PTR_ERR(my_class);
goto fail_class_create;
}
my_device = device_create(my_class, NULL, my_dev, NULL, DEVICE_NAME);
if (IS_ERR(my_device)) {
ret = PTR_ERR(my_device);
goto fail_device_create;
}
my_input_dev = input_allocate_device();
if (!my_input_dev) {
ret = -ENOMEM;
goto fail_input_allocate_device;
}
my_input_dev->name = DEVICE_NAME;
my_input_dev->phys = "my_input_device";
my_input_dev->id.bustype = BUS_VIRTUAL;
my_input_dev->id.vendor = 0x0001;
my_input_dev->id.product = 0x0001;
my_input_dev->id.version = 0x0100;
set_bit(EV_KEY, my_input_dev->evbit);
set_bit(KEY_A, my_input_dev->keybit);
ret = input_register_device(my_input_dev);
if (ret)
goto fail_input_register_device;
return 0;
fail_input_register_device:
input_free_device(my_input_dev);
fail_input_allocate_device:
device_destroy(my_class, my_dev);
fail_device_create:
class_destroy(my_class);
fail_class_create:
cdev_del(&my_cdev);
fail_cdev_add:
unregister_chrdev_region(my_dev, 1);
fail_alloc_chrdev_region:
return ret;
}
static void __exit my_exit(void)
{
input_unregister_device(my_input_dev);
input_free_device(my_input_dev);
device_destroy(my_class, my_dev);
class_destroy(my_class);
cdev_del(&my_cdev);
unregister_chrdev_region(my_dev, 1);
}
module_init(my_init);
module_exit(my_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple input driver");
阅读全文