分享份关于Linux的dido驱动
#include
#include
#include
#include
static struct class *shaohuawlw_dido;
static struct device *di_device;
static struct device *do_device;
// di1
static ssize_t get_di1(struct device *dev, struct device_attribute *attr, char *buf)
{
int value = gpio_get_value(32);
return snprintf(buf, PAGE_SIZE, "%d\n", value);
}
static ssize_t set_di1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int value;
sscanf(buf, "%d", &value);
gpio_set_value(32, value);
return count;
}
static DEVICE_ATTR(di1, 0664, get_di1, set_di1);
// di2
static ssize_t get_di2(struct device *dev, struct device_attribute *attr, char *buf)
{
int value = gpio_get_value(33);
return snprintf(buf, PAGE_SIZE, "%d\n", value);
}
static ssize_t set_di2(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int value;
sscanf(buf, "%d", &value);
gpio_set_value(33, value);
return count;
}
static DEVICE_ATTR(di2, 0664, get_di2, set_di2);
// di3
static ssize_t get_di3(struct device *dev, struct device_attribute *attr, char *buf)
{
int value = gpio_get_value(34);
return snprintf(buf, PAGE_SIZE, "%d\n", value);
}
static ssize_t set_di3(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int value;
sscanf(buf, "%d", &value);
gpio_set_value(34, value);
return count;
}
static DEVICE_ATTR(di3, 0664, get_di3, set_di3);
// di4
static ssize_t get_di4(struct device *dev, struct device_attribute *attr, char *buf)
{
int value = gpio_get_value(35);
return snprintf(buf, PAGE_SIZE, "%d\n", value);
}
static ssize_t set_di4(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int value;
sscanf(buf, "%d", &value);
gpio_set_value(35, value);
return count;
}
static DEVICE_ATTR(di4, 0664, get_di4, set_di4);
// do1
static ssize_t get_do1(struct device *dev, struct device_attribute *attr, char *buf)
{
int value = gpio_get_value(64);
return snprintf(buf, PAGE_SIZE, "%d\n", value);
}
static ssize_t set_do1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int value;
sscanf(buf, "%d", &value);
gpio_set_value(64, value);
return count;
}
static DEVICE_ATTR(do1, 0664, get_do1, set_do1);
// do2
static ssize_t get_do2(struct device *dev, struct device_attribute *attr, char *buf)
{
int value = gpio_get_value(65);
return snprintf(buf, PAGE_SIZE, "%d\n", value);
}
static ssize_t set_do2(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int value;
sscanf(buf, "%d", &value);
gpio_set_value(65, value);
return count;
}
static DEVICE_ATTR(do2, 0664, get_do2, set_do2);
// do3
static ssize_t get_do3(struct device *dev, struct device_attribute *attr, char *buf)
{
int value = gpio_get_value(66);
return snprintf(buf, PAGE_SIZE, "%d\n", value);
}
static ssize_t set_do3(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int value;
sscanf(buf, "%d", &value);
gpio_set_value(66, value);
return count;
}
static DEVICE_ATTR(do3, 0664, get_do3, set_do3);
// do4
static ssize_t get_do4(struct device *dev, struct device_attribute *attr, char *buf)
{
int value = gpio_get_value(67);
return snprintf(buf, PAGE_SIZE, "%d\n", value);
}
static ssize_t set_do4(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int value;
sscanf(buf, "%d", &value);
gpio_set_value(67, value);
return count;
}
static DEVICE_ATTR(do4, 0664, get_do4, set_do4);
static int __init dido_init(void)
{
// 创建设备类
shaohuawlw_dido = class_create(THIS_MODULE, "dido"); // CLASS_NAME
if (IS_ERR(shaohuawlw_dido))
{
printk(KERN_ALERT "===== DIDO Failed to create class\n");
return PTR_ERR(shaohuawlw_dido);
}
// 创建设备节点
di_device = device_create(shaohuawlw_dido, NULL, MKDEV(0, 0), NULL, "di"); // DEVICE_NAME
do_device = device_create(shaohuawlw_dido, NULL, MKDEV(0, 0), NULL, "do"); // DEVICE_NAME
if (IS_ERR(di_device))
{
printk(KERN_ALERT "===== DIDO Failed to create device\n");
class_destroy(shaohuawlw_dido);
return PTR_ERR(di_device);
}
if (IS_ERR(do_device))
{
printk(KERN_ALERT "===== DIDO Failed to create device\n");
class_destroy(shaohuawlw_dido);
return PTR_ERR(do_device);
}
// 添加设备属性
// di
device_create_file(di_device, &dev_attr_di1);
device_create_file(di_device, &dev_attr_di2);
device_create_file(di_device, &dev_attr_di3);
device_create_file(di_device, &dev_attr_di4);
//do
device_create_file(do_device, &dev_attr_do1);
device_create_file(do_device, &dev_attr_do2);
device_create_file(do_device, &dev_attr_do3);
device_create_file(do_device, &dev_attr_do4);
/*
if (device_create_file(di_device, &dev_attr_do1) < 0)
{
printk(KERN_ALERT "===== DIDO Failed to create device attribute\n");
device_destroy(shaohuawlw_dido, MKDEV(0, 0));
class_destroy(shaohuawlw_dido);
return -ENOMEM;
}
if (device_create_file(do_device, &dev_attr_do1) < 0)
{
printk(KERN_ALERT "===== DIDO Failed to create device attribute\n");
device_destroy(shaohuawlw_dido, MKDEV(0, 0));
class_destroy(shaohuawlw_dido);
return -ENOMEM;
}
*/
// 初始化 GPIO 端口
//di
gpio_request(32, "di1");
gpio_request(33, "di2");
gpio_request(34, "di3");
gpio_request(35, "di4");
gpio_direction_input(32);
gpio_direction_input(33);
gpio_direction_input(34);
gpio_direction_input(35);
// do
gpio_request(64, "do1");
gpio_request(65, "do2");
gpio_request(66, "do3");
gpio_request(67, "do4");
gpio_direction_output(64, 0);
gpio_direction_output(65, 0);
gpio_direction_output(66, 0);
gpio_direction_output(67, 0);
/*
if (gpio_request(32, "my_gpio") < 0)
{
printk(KERN_ALERT "===== DIDO Failed to request GPIO pin\n");
device_remove_file(hmi170_do1, &dev_attr_do1_state);
device_destroy(shaohuawlw_dido, MKDEV(0, 0));
class_destroy(shaohuawlw_dido);
return -ENODEV;
}
gpio_direction_output(90, 0);
*/
printk(KERN_INFO "===== DIDO Device created\n");
return 0;
}
static void __exit dido_exit(void)
{
// 释放 GPIO 端口
gpio_free(32);
gpio_free(33);
gpio_free(34);
gpio_free(35);
gpio_free(64);
gpio_free(65);
gpio_free(66);
gpio_free(67);
// 移除设备属性
// di
device_remove_file(di_device, &dev_attr_di1);
device_remove_file(di_device, &dev_attr_di2);
device_remove_file(di_device, &dev_attr_di3);
device_remove_file(di_device, &dev_attr_di4);
// do
device_remove_file(do_device, &dev_attr_do1);
device_remove_file(do_device, &dev_attr_do2);
device_remove_file(do_device, &dev_attr_do3);
device_remove_file(do_device, &dev_attr_do4);
// 销毁设备节点
device_destroy(di_device, MKDEV(0, 0));
device_destroy(do_device, MKDEV(0, 0));
// 销毁设备类
class_destroy(shaohuawlw_dido);
printk(KERN_INFO "===== DIDO Device destroyed\n");
}
module_init(dido_init);
module_exit(dido_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("shaohuawlw");
MODULE_DESCRIPTION("shaohuawlw-dido device driver");