- 论坛徽章:
- 0
|
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <mach/map.h>
#include <plat/gpio-cfg.h>
#include <plat/regs-clock.h>
#include <plat/regs-gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-bank-n.h>
MODULE_AUTHOR("HaNdAEr" ;
MODULE_LICENSE("GPL" ;
struct input_dev* button_devp;
static char *name = "s3c6410_buttons";
struct button_irq_desc{
int irq;
//int pin;
int number;
char *name;
};
static struct button_irq_desc button_irqs[] = {
{ IRQ_EINT(0), /*S3C64XX_GPN(0), */ 0, "KEY1"},
{ IRQ_EINT(1), /*S3C64XX_GPN(1), */ 1, "KEY2"},
{ IRQ_EINT(2), /*S3C64XX_GPN(2), */ 2, "KEY3"},
{ IRQ_EINT(3), /*S3C64XX_GPN(3), */ 3, "KEY4"},
{ IRQ_EINT(4), /*S3C64XX_GPN(4), */ 4, "KEY5"},
{ IRQ_EINT(5), /*S3C64XX_GPN(5), */ 5, "KEY6"},
{ IRQ_EINT(19), /*S3C64XX_GPL(19),*/ 19, "KEY7"},
{ IRQ_EINT(20), /*S3C64XX_GPL(20),*/ 20, "KEY8"},
};
static irqreturn_t button_interrupt(int irq, void* dev_id)
{
struct button_irq_desc *button_irqs = (struct button_irq_desc*)dev_id;
int updown,reportval;
if(button_irqs->number <0){
return -1;
}
if(button_irqs->number <=5){
updown = readl(S3C64XX_GPNDAT) & ( 0x1 << button_irqs->number);
}else{
updown = readl(S3C64XX_GPLDAT) & ( 0x1 << button_irqs->number);
}
reportval = updown ? 0 : 1;
switch(button_irqs->number)
{
case 0:
input_report_key(button_devp, BTN_0, reportval);
break;
case 1:
input_report_key(button_devp, BTN_1, reportval);
break;
case 2:
input_report_key(button_devp, BTN_2, reportval);
break;
case 3:
input_report_key(button_devp, BTN_3, reportval);
break;
case 4:
input_report_key(button_devp, BTN_4, reportval);
break;
case 5:
input_report_key(button_devp, BTN_5, reportval);
break;
case 6:
input_report_key(button_devp, BTN_6, reportval);
break;
case 7:
input_report_key(button_devp, BTN_7, reportval);
break;
default:
break;
}
input_sync(button_devp);
return IRQ_RETVAL(IRQ_HANDLED);
}
static int __init button_init(void)
{
int i;
int err = 0;
int ret = 0;
struct input_dev *input_dev;
input_dev = input_allocate_device();
if(!input_dev){
printk(KERN_ERR"Unable to alloc the input device!!\n" ;
}
button_devp = input_dev;
button_devp->evbit[0] = BIT(EV_KEY) | BIT(EV_SYN);
button_devp->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0) | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) |
BIT_MASK(BTN_3) | BIT_MASK(BTN_4) | BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7);
button_devp->name = name;
for(i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++)
{
err = request_irq(button_irqs[i].irq, button_interrupt, IRQ_TYPE_EDGE_BOTH, button_irqs[i].name, (void *)&button_irqs[i]);
if(err)
{
break;
}
}
if(err)
{
i--;
for(; i >= 0; i--)
{
if(button_irqs[i].irq < 0)
{
continue;
}
disable_irq(button_irqs[i].irq);
free_irq(button_irqs[i].irq, (void*)&button_irqs[i]);
}
return -EBUSY;
}
/*
set_bit(EV_KEY, button_devp->evbit);
set_bit(BTN_0, button_devp->keybit);
set_bit(BTN_1, button_devp->keybit);
set_bit(BTN_2, button_devp->keybit);
set_bit(BTN_3, button_devp->keybit);
set_bit(BTN_4, button_devp->keybit);
set_bit(BTN_5, button_devp->keybit);
set_bit(BTN_6, button_devp->keybit);
set_bit(BTN_7, button_devp->keybit);
*/
ret = input_register_device(button_devp);
if(ret < 0){
printk("input_register_device(): failed !! \n" ;
}
return ret;
}
static void __exit button_exit(void)
{
int i;
for(i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++)
{
disable_irq(button_irqs[i].irq);
free_irq(button_irqs[i].irq, (void*)&button_irqs[i]);
}
input_unregister_device(button_devp);
}
module_init(button_init);
module_exit(button_exit);
每按下或者抬起都多出现一次空数据!!!!
大家帮忙测一下为什么出现问题! |
|