driver/3-new-led/new_char.c

139 lines
3.9 KiB
C
Raw Permalink Normal View History

2024-01-30 13:39:31 +00:00
/*
* @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @Date: 2023-08-19 09:31:52
* @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @LastEditTime: 2023-08-19 10:42:49
* @FilePath: /3-new-led/led.c
* @Description: ,`customMade`, koroFileHeader查看配置 : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
/***
* configuration
*/
// DEV_NAME
#define dev_name "newchr"
// DEV_ID配置
#define DEV_ID_STATIC 1
#if DEV_ID_STATIC
#define DEV_ID_MAJOR 80
#define DEV_ID_MINOR 0
#endif
struct _dev_info
{
dev_t dev_id;
struct cdev cdev;
struct class *class;
struct device *device;
} dev_info = {0};
/***
* code
*/
static ssize_t tis_module_read(struct file *file, char __user *out, size_t size, loff_t *offt)
{
printk("%s: module read\n", dev_name);
return 0;
}
static ssize_t tis_module_write(struct file *file, const char __user *in, size_t size, loff_t *offt)
{
printk("%s: module write\n", dev_name);
return 0;
}
static int tis_module_open(struct inode *inode, struct file *file)
{
printk("%s: module open\n", dev_name);
return 0;
}
static int tis_module_release(struct inode *inode, struct file *file)
{
printk("%s: module release\n", dev_name);
return 0;
}
static struct file_operations tis_module_f = {
.owner = THIS_MODULE,
.write = tis_module_write,
.read = tis_module_read,
.open = tis_module_open,
.release = tis_module_release,
};
static int __init tis_module_init(void)
{
int ret;
// 申请dev id
#if (DEV_ID_STATIC)
dev_info.dev_id = MKDEV(DEV_ID_MAJOR, DEV_ID_MINOR);
ret = register_chrdev_region(dev_info.dev_id, 1, dev_name);
if (ret < 0)
{
printk("[%s] dev_id get failed\n",dev_name);
return ret;
}
#else
ret = alloc_chrdev_region(&dev_info.dev_id, 0, 1, dev_name);
if (ret)
{
printk("[%s] dev_id get failed\n");
return ret;
}
#endif
// 注册设备
dev_info.cdev.owner = THIS_MODULE;
cdev_init(&dev_info.cdev, &tis_module_f);
ret = cdev_add(&dev_info.cdev, dev_info.dev_id, 1);
if (ret < 0)
{
printk("[%s] cdev_add failed\n", dev_name);
goto del_unregister;
}
// 创建设备
dev_info.class = class_create(THIS_MODULE, dev_name);
if (IS_ERR(dev_info.class))
{
printk("[%s] class create failed\n", dev_name);
goto del_cdev;
}
dev_info.device = device_create(dev_info.class, NULL, dev_info.dev_id, NULL, dev_name);
if (IS_ERR(dev_info.device))
{
printk("[%s] dev create failed\n", dev_name);
goto destroy_class;
}
printk("[%s] init success\n", dev_name);
return 0;
destroy_class:
class_destroy(dev_info.class);
del_cdev:
cdev_del(&dev_info.cdev);
del_unregister:
unregister_chrdev_region(dev_info.dev_id, 1);
return -EIO;
}
static void __exit tis_module_exit(void)
{
/* 注销字符设备驱动 */
cdev_del(&dev_info.cdev); /* 删除cdev */
unregister_chrdev_region(dev_info.dev_id, 1); /* 注销设备号 */
device_destroy(dev_info.class, dev_info.dev_id);
class_destroy(dev_info.class);
printk("[%s] exit success\n", dev_name);
}
module_init(tis_module_init);
module_exit(tis_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("chenyf");
MODULE_INFO(intree, "Y");