基于Dragonboard 410c的燃气烟雾检测器(四)

来源:互联网 发布:禁止在淘宝网出售 编辑:程序博客网 时间:2024/04/19 23:28

  前面已经简单的将燃气烟雾检测模块MQ-2和温湿度检测模块dht11的底层驱动实现了,下面再加一个简单的红灯的驱动,用于报警:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/sysfs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/input.h>
#include <linux/mutex.h>
#include <linux/ctype.h>
#include <linux/pm_runtime.h>
#include <linux/device.h>
#include <linux/irq.h>
#include <linux/of_gpio.h>
 
#include <linux/wait.h>
#include <asm/uaccess.h>  
 
struct red_data{
    int pin;    
    int d;
    struct mutex data_lock;
};
 
static int parse_dt(struct platform_device* pdev,struct red_data* data){
    int rc;
    struct device_node* node = pdev->dev.of_node;
    data->pin = of_get_named_gpio(node,"thunder,pin",0);
    if(gpio_is_valid(data->pin)){
        rc = gpio_request(data->pin,"red_pin");
        if(rc < 0){
            pr_err("Unable to request pin gpio\n");
        }
        gpio_direction_output(data->pin, 1);
        data->d = 1;
    }
    return 0;
}
 
static ssize_t red_store_value(struct device *dev,                                                                                                                                                   
                struct device_attribute *attr,
                const char *buf, size_t size){
    struct red_data* data = dev_get_drvdata(dev);
    int da = simple_strtoul(buf,NULL,10);
    if(da == 1){
        gpio_set_value(data->pin, 1);
    }else{
        gpio_set_value(data->pin, 0);
    }
    data->d = da;
    return size;
}
 
static ssize_t red_show_value(struct device *dev,
                                  struct device_attribute* attr,char* buf){
    struct red_data* data = dev_get_drvdata(dev);
    ssize_t da;
    mutex_lock(&data->data_lock);
    da = sprintf(buf, "%d\n", data->d);
    mutex_unlock(&data->data_lock);
    return da;
}
 
static DEVICE_ATTR(value,0644,red_show_value,red_store_value);
 
static int red_probe(struct platform_device *pdev){
    struct red_data* data;
    int result;
    data = kmalloc(sizeof(struct red_data),GFP_KERNEL);
    if(!data){
        pr_err("%s kmalloc error\n",__FUNCTION__);
        return -ENOMEM;   
    }
    dev_set_drvdata(&pdev->dev,data);
    result = parse_dt(pdev,data);
    if(result<0){
        pr_err("%s error when parse dt\n",__FUNCTION__);
        result = -EINVAL;
        goto err_parse_dt;
    }
 
    mutex_init(&data->data_lock);
    
    result=sysfs_create_file(&pdev->dev.kobj,&dev_attr_value.attr);
    printk("red probe success\n");
    return 0;
err_parse_dt:
    kfree(data);
    printk("red probe failed\n");
    return result;
}
static int red_remove(struct platform_device *pdev){
    return 0;
}
 
 
static struct of_device_id red_match_table[] = {
    { .compatible = "thunder,red",},
    { },
};
 
 
 
static struct platform_driver red_driver = {
    .probe = red_probe,
    .remove = red_remove,
    .driver = {
        .owner = THIS_MODULE,
        .name = "red",
        .of_match_table = red_match_table,
    },
};
 
 
module_platform_driver(red_driver);
MODULE_AUTHOR("RED");
MODULE_LICENSE("GPL v2");


节点路径:/sys/bus/platform/drivers/red/rgb_red.64/value

这个节点是可读可写的,当节点值为0,灯亮报警;当节点值为1等灭,正常。

到此大部分底层需要的驱动都准备好了,节点也都有了,接下来就是向上走,大致流程:driver->hal->jni->app