首页 > 代码库 > Linux嵌入式学习-烟雾传感器驱动-字符设备驱动-按键驱动

Linux嵌入式学习-烟雾传感器驱动-字符设备驱动-按键驱动

MQ-2烟雾气敏传感器模块在X210v3开发板上的驱动。

现在需要一个MQ-2烟雾气敏传感器模块的驱动。其检测烟雾超过一定的标准后,会返回一个不同的电平,和按键驱动差不多。

但是在编写驱动的时候,需要用GPH2_3号引脚。但是在内核中先ioremap地址然后配置,发现无法控制gpio,也无法进入中断。

后来发现,如果需要使用gpio,需要先申请,然后才能使用。

具体程序如下:

#include <linux/module.h>

#include <linux/init.h>

#include <linux/miscdevice.h>

#include <linux/interrupt.h>

#include <linux/io.h>

#include <linux/fs.h>

#include <linux/slab.h>

#include <asm/irq.h>

#include <linux/random.h>

#include <linux/uaccess.h>

#include <linux/device.h>

#include <mach/gpio.h>



#define GPH2CON 0xE0200c60

#define GPH2DAT 0xE0200c64


static struct class *fog_class;     //创建类

static struct class_device *fog_class_devs;   //创建类对应的设备


struct work_struct *work1;


struct timer_list fogs_timer;


unsigned int *gpio_data;


unsigned int fog_num = 0;


wait_queue_head_t  fog_q;


void work1_func(struct work_struct *work)
{

    mod_timer(&fogs_timer, jiffies + (HZ /10));

}


void fogs_timer_function(unsigned long data)
{

    unsigned int fog_val;


    fog_val = readw(gpio_data)&0x08;
    if (fog_val == 0)
    {

       fog_num = 1;

       printk("press down\n");

    }

    wake_up(&fog_q);

}



irqreturn_t fog_int(int irq, void *dev_id)
{

    schedule_work(work1);



    //return 0;

    return IRQ_HANDLED;

}


void fog_hw_init()
{

    unsigned int *gpio_config;

    unsigned short data;



    gpio_request(S5PV210_GPH2(3),"my_fog");

    gpio_config = ioremap(GPH2CON,4);

    data = readw(gpio_config);

    data &= ~(0b1111<<12);

    data |= 0b1111<<12;
    writew(data,gpio_config);

    gpio_data = ioremap(GPH2DAT,1);



}


int fog_open(struct inode *node,struct file *filp)
{
    return 0;
}


ssize_t fog_read(struct file *filp, char __user *buf, size_t size, loff_t *pos)

{

    wait_event(fog_q,fog_num);

   // printk("in kernel :fog num is %d\n",fog_num);

    copy_to_user(buf, &fog_num, 4);

    fog_num = 0;

    return 4;

}



struct file_operations fog_fops =

{

    .open = fog_open,

    .read = fog_read,

};



struct miscdevice fog_miscdev = {

    .minor = 200,

    .name = "fog",

    .fops = &fog_fops,

};



int major;

static int fog_init()

{

    int ret;

    major = register_chrdev( 0,"fog_drv", &fog_fops );

    fog_class = class_create(THIS_MODULE,"fog_class");

    fog_class_devs = device_create(fog_class,NULL,MKDEV(major,0),NULL,"my_fog");

    if (ret !=0)

        printk("register fail!\n");

    //×¢2á?D????àí3ìDò

    request_irq(IRQ_EINT(27),fog_int,IRQF_TRIGGER_FALLING,"fog",0);


    //°??ü3?ê??ˉ

    fog_hw_init();

    //. ????1€×÷

    work1 = kmalloc(sizeof(struct work_struct),GFP_KERNEL);

    INIT_WORK(work1, work1_func);

    /* 3?ê??ˉ??ê±?÷ */

    init_timer(&fogs_timer);

    fogs_timer.function  = fogs_timer_function;


    /* ?ò?úo?×¢2áò?????ê±?÷ */

    add_timer(&fogs_timer);


    /*3?ê??ˉμè?y?óáD*/

    init_waitqueue_head(&fog_q);
    return 0;

}


static void fog_exit()

{

    del_timer(&fogs_timer);

    unregister_chrdev( major, "fog_drv" );

    device_unregister(fog_class_devs);

    class_destroy(fog_class);


}


module_init(fog_init);

module_exit(fog_exit);

MODULE_LICENSE("GPL");

 

Linux嵌入式学习-烟雾传感器驱动-字符设备驱动-按键驱动