基于中断的键盘驱动
时间:2010-08-01 来源:unixeye
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#define DEVICE_NAME "Key-16"
#define KEY_MAJOR 232 static int keyValue; static DECLARE_WAIT_QUEUE_HEAD(key_waitq); static volatile int ev_press = 0; struct key_irq_desc
{
int irq;
unsigned long flags;
char *name;
}; static struct key_irq_desc key_irqs [] = {
{IRQ_EINT19, IRQF_TRIGGER_FALLING, "KSCAN1"},
{IRQ_EINT11, IRQF_TRIGGER_FALLING, "KSCAN2"},
{IRQ_EINT2, IRQF_TRIGGER_FALLING, "KSCAN3"},
{IRQ_EINT0, IRQF_TRIGGER_FALLING, "KSCAN4"},
}; static void set_pin(void)
{
s3c2410_gpio_cfgpin(S3C2410_GPG2,S3C2410_GPG2_OUTP);
s3c2410_gpio_cfgpin(S3C2410_GPG6,S3C2410_GPG6_OUTP);
s3c2410_gpio_cfgpin(S3C2410_GPE11,S3C2410_GPE11_OUTP);
s3c2410_gpio_cfgpin(S3C2410_GPE13,S3C2410_GPE13_OUTP); s3c2410_gpio_setpin(S3C2410_GPG2,0);
s3c2410_gpio_setpin(S3C2410_GPG6,0);
s3c2410_gpio_setpin(S3C2410_GPE11,0);
s3c2410_gpio_setpin(S3C2410_GPE13,0);
}
static int Key_16_scan(void)
{
s3c2410_gpio_cfgpin(S3C2410_GPF0,S3C2410_GPF0_INP); s3c2410_gpio_cfgpin(S3C2410_GPF2,S3C2410_GPF2_INP);
s3c2410_gpio_cfgpin(S3C2410_GPG3,S3C2410_GPG3_INP); s3c2410_gpio_cfgpin(S3C2410_GPG11,S3C2410_GPG11_INP); s3c2410_gpio_setpin(S3C2410_GPE11,0);s3c2410_gpio_setpin(S3C2410_GPE13,1);
s3c2410_gpio_setpin(S3C2410_GPG2,1);s3c2410_gpio_setpin(S3C2410_GPG6,1);
if(s3c2410_gpio_getpin(S3C2410_GPF0) == 0) return 0x0a;
if(s3c2410_gpio_getpin(S3C2410_GPF2) == 0) return 0x07;
if(s3c2410_gpio_getpin(S3C2410_GPG3) == 0) return 0x04;
if(s3c2410_gpio_getpin(S3C2410_GPG11) == 0) return 0x01; s3c2410_gpio_setpin(S3C2410_GPE11,1);s3c2410_gpio_setpin(S3C2410_GPE13,0);
s3c2410_gpio_setpin(S3C2410_GPG2,1);s3c2410_gpio_setpin(S3C2410_GPG6,1);
if(s3c2410_gpio_getpin(S3C2410_GPF0) == 0) return 0x0C;
if(s3c2410_gpio_getpin(S3C2410_GPF2) == 0) return 0x09;
if(s3c2410_gpio_getpin(S3C2410_GPG3) == 0) return 0x06;
if(s3c2410_gpio_getpin(S3C2410_GPG11) == 0) return 0x03; s3c2410_gpio_setpin(S3C2410_GPE11,1);s3c2410_gpio_setpin(S3C2410_GPE13,1);
s3c2410_gpio_setpin(S3C2410_GPG2,0);s3c2410_gpio_setpin(S3C2410_GPG6,1);
if(s3c2410_gpio_getpin(S3C2410_GPF0) == 0) return 0x10;
if(s3c2410_gpio_getpin(S3C2410_GPF2) == 0) return 0x0F;
if(s3c2410_gpio_getpin(S3C2410_GPG3) == 0) return 0x0E;
if(s3c2410_gpio_getpin(S3C2410_GPG11) == 0) return 0x0D; s3c2410_gpio_setpin(S3C2410_GPE11,1);s3c2410_gpio_setpin(S3C2410_GPE13,1);
s3c2410_gpio_setpin(S3C2410_GPG2,1);s3c2410_gpio_setpin(S3C2410_GPG6,0);
if(s3c2410_gpio_getpin(S3C2410_GPF0) == 0) return 0x0B;
if(s3c2410_gpio_getpin(S3C2410_GPF2) == 0) return 0x08;
if(s3c2410_gpio_getpin(S3C2410_GPG3) == 0) return 0x05;
if(s3c2410_gpio_getpin(S3C2410_GPG11) == 0) return 0x02;
else return 0; } static irqreturn_t Key_16_interrupt(int irq,void *dev_id)
{
disable_irq_nosync(irq);
ev_press = 1;
wake_up_interruptible(&key_waitq);
enable_irq(irq);
return IRQ_RETVAL(IRQ_HANDLED);
}
static int Key_16_open(struct inode *inode, struct file *file)
{
int i;
int err; set_pin();
for(i = 0; i < sizeof(key_irqs)/sizeof(key_irqs[0]); i++)
{
err = request_irq(key_irqs[i].irq, Key_16_interrupt,key_irqs[i].flags, key_irqs[i].name,(void *)&keyValue);
if(err)
break;
} return 0;
} static int Key_16_read(struct file *file, char __user *buff, size_t count, loff_t *offp)
{
unsigned long err; wait_event_interruptible(key_waitq, ev_press);
ev_press = 0; keyValue = Key_16_scan();
s3c2410_gpio_cfgpin(S3C2410_GPF0,S3C2410_GPF0_EINT0); s3c2410_gpio_cfgpin(S3C2410_GPF2,S3C2410_GPF2_EINT2);
s3c2410_gpio_cfgpin(S3C2410_GPG3,S3C2410_GPG3_EINT11); s3c2410_gpio_cfgpin(S3C2410_GPG11,S3C2410_GPG11_EINT19);
set_pin();
if(keyValue != 0)
{
err = copy_to_user(buff, &keyValue, min(sizeof(keyValue), count));
memset(&keyValue, 0, sizeof(keyValue)); return err ? -EFAULT : 0;
}
return 0;
} static struct file_operations Key_16_fops =
{
.owner = THIS_MODULE,
.open = Key_16_open,
.read = Key_16_read,
}; static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &Key_16_fops,
}; static int __init Key_16_init(void)
{
int ret;
ret = misc_register(&misc);
printk (DEVICE_NAME" initialized\n"); return ret;
} static void __exit Key_16_exit(void)
{
misc_deregister(&misc);
} module_init(Key_16_init);
module_exit(Key_16_exit);
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#define DEVICE_NAME "Key-16"
#define KEY_MAJOR 232 static int keyValue; static DECLARE_WAIT_QUEUE_HEAD(key_waitq); static volatile int ev_press = 0; struct key_irq_desc
{
int irq;
unsigned long flags;
char *name;
}; static struct key_irq_desc key_irqs [] = {
{IRQ_EINT19, IRQF_TRIGGER_FALLING, "KSCAN1"},
{IRQ_EINT11, IRQF_TRIGGER_FALLING, "KSCAN2"},
{IRQ_EINT2, IRQF_TRIGGER_FALLING, "KSCAN3"},
{IRQ_EINT0, IRQF_TRIGGER_FALLING, "KSCAN4"},
}; static void set_pin(void)
{
s3c2410_gpio_cfgpin(S3C2410_GPG2,S3C2410_GPG2_OUTP);
s3c2410_gpio_cfgpin(S3C2410_GPG6,S3C2410_GPG6_OUTP);
s3c2410_gpio_cfgpin(S3C2410_GPE11,S3C2410_GPE11_OUTP);
s3c2410_gpio_cfgpin(S3C2410_GPE13,S3C2410_GPE13_OUTP); s3c2410_gpio_setpin(S3C2410_GPG2,0);
s3c2410_gpio_setpin(S3C2410_GPG6,0);
s3c2410_gpio_setpin(S3C2410_GPE11,0);
s3c2410_gpio_setpin(S3C2410_GPE13,0);
}
static int Key_16_scan(void)
{
s3c2410_gpio_cfgpin(S3C2410_GPF0,S3C2410_GPF0_INP); s3c2410_gpio_cfgpin(S3C2410_GPF2,S3C2410_GPF2_INP);
s3c2410_gpio_cfgpin(S3C2410_GPG3,S3C2410_GPG3_INP); s3c2410_gpio_cfgpin(S3C2410_GPG11,S3C2410_GPG11_INP); s3c2410_gpio_setpin(S3C2410_GPE11,0);s3c2410_gpio_setpin(S3C2410_GPE13,1);
s3c2410_gpio_setpin(S3C2410_GPG2,1);s3c2410_gpio_setpin(S3C2410_GPG6,1);
if(s3c2410_gpio_getpin(S3C2410_GPF0) == 0) return 0x0a;
if(s3c2410_gpio_getpin(S3C2410_GPF2) == 0) return 0x07;
if(s3c2410_gpio_getpin(S3C2410_GPG3) == 0) return 0x04;
if(s3c2410_gpio_getpin(S3C2410_GPG11) == 0) return 0x01; s3c2410_gpio_setpin(S3C2410_GPE11,1);s3c2410_gpio_setpin(S3C2410_GPE13,0);
s3c2410_gpio_setpin(S3C2410_GPG2,1);s3c2410_gpio_setpin(S3C2410_GPG6,1);
if(s3c2410_gpio_getpin(S3C2410_GPF0) == 0) return 0x0C;
if(s3c2410_gpio_getpin(S3C2410_GPF2) == 0) return 0x09;
if(s3c2410_gpio_getpin(S3C2410_GPG3) == 0) return 0x06;
if(s3c2410_gpio_getpin(S3C2410_GPG11) == 0) return 0x03; s3c2410_gpio_setpin(S3C2410_GPE11,1);s3c2410_gpio_setpin(S3C2410_GPE13,1);
s3c2410_gpio_setpin(S3C2410_GPG2,0);s3c2410_gpio_setpin(S3C2410_GPG6,1);
if(s3c2410_gpio_getpin(S3C2410_GPF0) == 0) return 0x10;
if(s3c2410_gpio_getpin(S3C2410_GPF2) == 0) return 0x0F;
if(s3c2410_gpio_getpin(S3C2410_GPG3) == 0) return 0x0E;
if(s3c2410_gpio_getpin(S3C2410_GPG11) == 0) return 0x0D; s3c2410_gpio_setpin(S3C2410_GPE11,1);s3c2410_gpio_setpin(S3C2410_GPE13,1);
s3c2410_gpio_setpin(S3C2410_GPG2,1);s3c2410_gpio_setpin(S3C2410_GPG6,0);
if(s3c2410_gpio_getpin(S3C2410_GPF0) == 0) return 0x0B;
if(s3c2410_gpio_getpin(S3C2410_GPF2) == 0) return 0x08;
if(s3c2410_gpio_getpin(S3C2410_GPG3) == 0) return 0x05;
if(s3c2410_gpio_getpin(S3C2410_GPG11) == 0) return 0x02;
else return 0; } static irqreturn_t Key_16_interrupt(int irq,void *dev_id)
{
disable_irq_nosync(irq);
ev_press = 1;
wake_up_interruptible(&key_waitq);
enable_irq(irq);
return IRQ_RETVAL(IRQ_HANDLED);
}
static int Key_16_open(struct inode *inode, struct file *file)
{
int i;
int err; set_pin();
for(i = 0; i < sizeof(key_irqs)/sizeof(key_irqs[0]); i++)
{
err = request_irq(key_irqs[i].irq, Key_16_interrupt,key_irqs[i].flags, key_irqs[i].name,(void *)&keyValue);
if(err)
break;
} return 0;
} static int Key_16_read(struct file *file, char __user *buff, size_t count, loff_t *offp)
{
unsigned long err; wait_event_interruptible(key_waitq, ev_press);
ev_press = 0; keyValue = Key_16_scan();
s3c2410_gpio_cfgpin(S3C2410_GPF0,S3C2410_GPF0_EINT0); s3c2410_gpio_cfgpin(S3C2410_GPF2,S3C2410_GPF2_EINT2);
s3c2410_gpio_cfgpin(S3C2410_GPG3,S3C2410_GPG3_EINT11); s3c2410_gpio_cfgpin(S3C2410_GPG11,S3C2410_GPG11_EINT19);
set_pin();
if(keyValue != 0)
{
err = copy_to_user(buff, &keyValue, min(sizeof(keyValue), count));
memset(&keyValue, 0, sizeof(keyValue)); return err ? -EFAULT : 0;
}
return 0;
} static struct file_operations Key_16_fops =
{
.owner = THIS_MODULE,
.open = Key_16_open,
.read = Key_16_read,
}; static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &Key_16_fops,
}; static int __init Key_16_init(void)
{
int ret;
ret = misc_register(&misc);
printk (DEVICE_NAME" initialized\n"); return ret;
} static void __exit Key_16_exit(void)
{
misc_deregister(&misc);
} module_init(Key_16_init);
module_exit(Key_16_exit);
相关阅读 更多 +