红外模块android驱动添加

xiaoxiao2021-02-28  68

  红外模块在很多方面都有应用,比如:测距,避障,报警等,由于我们要利用红外模块实现一个类似报警的功能,所以,在android5.1里面添加了如下红外模块驱动。

#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/i2c.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/jiffies.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 doorbell_data{     int enable;     int poll_time;       //50 ms       int rx_gpio;     //13     int irq;       int distance;                      struct mutex data_lock;         bool data_ready;              wait_queue_head_t data_queue;       struct delayed_work cmd_work;      };   static irqreturn_t doorbell_interrupt_handler(int irq, void *ptr){     struct doorbell_data* data = (struct doorbell_data*)ptr;     mutex_lock(&data->data_lock);     data->distance = 1;     mutex_unlock(&data->data_lock);     data-> data_ready = true;     wake_up_interruptible(&data->data_queue);     return IRQ_HANDLED; }   static void cmd_work_func(struct work_struct* work){     struct doorbell_data* data = container_of(work,struct doorbell_data,cmd_work.work);     if(gpio_get_value(data->rx_gpio)){         data->distance = 0;     }     data->data_ready = true;     wake_up_interruptible(&data->data_queue);     schedule_delayed_work(&data->cmd_work,msecs_to_jiffies(data->poll_time)); }   static int parse_dt(struct platform_device* pdev,struct doorbell_data* data){     int rc;     struct device_node* node = pdev->dev.of_node;     rc = of_property_read_u32(node,"thunder,poll_time",&data->poll_time);     if(rc){         pr_warning("%s you should point time\n",__FUNCTION__);         data->poll_time = 20;     }     data->rx_gpio = of_get_named_gpio(node,"thunder,gpio_rx",0);     if(gpio_is_valid(data->rx_gpio)){         rc = gpio_request(data->rx_gpio,"doorbell_rx_gpio");         if(rc < 0){             pr_err("uanble to request rx gpio\n");         }         rc = gpio_direction_input(data->rx_gpio);     }     if(data->rx_gpio<0){         pr_err("%s,error gpio\n",__FUNCTION__);         return -EINVAL;     }     return 0; }   static ssize_t doorbell_show_value(struct device *dev,                                   struct device_attribute* attr,char* buf){     struct doorbell_data* data = dev_get_drvdata(dev);     ssize_t lenth;     wait_event_interruptible(data->data_queue,data->data_ready);     data->data_ready = false;     mutex_lock(&data->data_lock);     lenth = sprintf(buf,"%d\n",data->distance);     printk("%d\n",data->distance);             mutex_unlock(&data->data_lock);     return lenth; }   static DEVICE_ATTR(value,0644,doorbell_show_value,NULL);   static int doorbell_probe(struct platform_device *pdev){     struct doorbell_data* data;     int result;     data = kmalloc(sizeof(struct doorbell_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;     }              data->irq = gpio_to_irq(data->rx_gpio);           result = request_irq(data->irq,doorbell_interrupt_handler,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"doorbell_int",data);         if(result<0){             pr_err("Unable to request irq\n");             goto err_parse_dt;         }     INIT_DELAYED_WORK(&data->cmd_work,cmd_work_func);     mutex_init(&data->data_lock);     init_waitqueue_head(&data->data_queue);          schedule_delayed_work(&data->cmd_work,msecs_to_jiffies(data->poll_time));     result=sysfs_create_file(&pdev->dev.kobj,&dev_attr_value.attr);     printk("doorbell probe sucess\n");     return 0; err_parse_dt:     kfree(data);     printk("doorbell probe failed\n");     return result; } static int doorbell_remove(struct platform_device *pdev){     return 0; }   static struct of_device_id doorbell_match_table[] = {     { .compatible = "thundersoft,doorbell",},     { }, };   static struct platform_driver doorbell_driver = {     .probe = doorbell_probe,     .remove = doorbell_remove,     .driver = {         .owner = THIS_MODULE,         .name = "doorbell-irda",         .of_match_table = doorbell_match_table,     }, };   module_platform_driver(doorbell_driver); MODULE_AUTHOR("IRDA"); MODULE_LICENSE("GPL v2");

转载请注明原文地址: https://www.6miu.com/read-71426.html

最新回复(0)