嵌入式Linux的gpio做dido输入输出驱动

嵌入式Linux的gpio做dido输入输出驱动

分享份关于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");

你可能感兴趣的:(Linux,linux)