diff --git a/gassensor.c b/gassensor.c new file mode 100644 index 0000000000000000000000000000000000000000..577c3f6a86a73acf4d1cbcd1d2fc3ebd1e18aeb8 --- /dev/null +++ b/gassensor.c @@ -0,0 +1,109 @@ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/fs.h> +#include <linux/uaccess.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/gpio.h> + +#include <asm/mach/map.h> +#include <asm/io.h> +#include <asm/uaccess.h> + +#define GAS_GPIO 23 //GPIO 23 +#define GAS_MAJOR_NUMBER 505 +#define GAS_DEV_NAME "gas_ioctl" + +//GPIO 23 +#define GPIO_BASE_ADDR 0x3F200000 +#define GPFSEL2 0x08 +#define GPSET0 0x1C +#define GPCLR0 0x28 + +#define IOCTL_MAGIC_NUMBER 'g' +#define IOCTL_CMD_GAS_ON _IO(IOCTL_MAGIC_NUMBER, 0) +#define IOCTL_CMD_GAS_OFF _IO(IOCTL_MAGIC_NUMBER, 1) + +#define HIGH 1 +#define LOW 0 + +static void __iomem *gpio_base; +volatile unsigned int *gpsel2; +volatile unsigned int *gpset1; +volatile unsigned int *gpclr1; + +int gas_open(struct inode *inode, struct file *flip) { + + printk(KERN_ALERT "gas driver open!!\n"); + + gpio_base = ioremap(GPIO_BASE_ADDR, 0x60); + gpsel2 = (volatile unsigned int *)(gpio_base + GPFSEL2); + gpset1 = (volatile unsigned int *)(gpio_base + GPSET0); + gpclr1 = (volatile unsigned int *)(gpio_base + GPCLR0); + + gpio_request(GAS_GPIO, "GAS_GPIO"); + //set direction in + *gpsel2 |= (0 << 9); + + + return 0; +} + +int gas_release(struct inode *inode, struct file *filp) { + printk(KERN_ALERT "gas driver closed!!\n"); + iounmap((void *)gpio_base); + return 0; +} + +long gas_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + + switch (cmd) { + case IOCTL_CMD_GAS_ON: + printk(KERN_ALERT "GAS detecting start!!\n"); + while (1) { + int i = gpio_get_value(GAS_GPIO); + if (i == HIGH) { + return HIGH; + } + else + return LOW; + } + ssleep(3); + + case IOCTL_CMD_GAS_OFF: + printk(KERN_ALERT "GAS off!!\n"); + *gpsel2 |= (1 << 9); + break; + } + return 0; +} + +static struct file_operations gas_fops = { + .owner = THIS_MODULE, + .open = gas_open, + .release = gas_release, + .unlocked_ioctl = gas_ioctl +}; + +int __init gas_init(void) { + if (register_chrdev(GAS_MAJOR_NUMBER, GAS_DEV_NAME, &gas_fops) < 0) + printk(KERN_ALERT "gas driver initialization fail\n"); + else + printk(KERN_ALERT "gas driver initailization success\n"); + + return 0; +} + +void __exit gas_exit(void) { + unregister_chrdev(GAS_MAJOR_NUMBER, GAS_DEV_NAME); + printk(KERN_ALERT "GAS driver exit done\n"); +} + +module_init(gas_init); +module_exit(gas_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sang"); +MODULE_DESCRIPTION("des");