交叉编译是arm-linux-gcc 4.4.1 内核是linux-2.6.28.6
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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(11),*/ 11, "KEY7"},
{ IRQ_EINT(20), /*S3C64XX_GPL(12),*/ 12, "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);
}
if(button_irqs->number == 11 || button_irqs->number == 12){
updown = readl(S3C64XX_GPLDAT) & ( 0x1 << button_irqs->number);
}
reportval = updown ? 0 : 1;
switch(button_irqs->number)
{
case IRQ_EINT(0):
input_report_key(button_devp, BTN_0, reportval);
break;
case IRQ_EINT(1):
input_report_key(button_devp, BTN_1, reportval);
break;
case IRQ_EINT(2):
input_report_key(button_devp, BTN_2, reportval);
break;
case IRQ_EINT(3):
input_report_key(button_devp, BTN_3, reportval);
break;
case IRQ_EINT(4):
input_report_key(button_devp, BTN_4, reportval);
break;
case IRQ_EINT(5):
input_report_key(button_devp, BTN_5, reportval);
break;
case IRQ_EINT(19):
input_report_key(button_devp, BTN_6, reportval);
break;
case IRQ_EINT(20):
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);
测试函数:
#include
#include
#include
#include
#include
#include
#include
#include
int main(void)
{
struct input_event ievent;
int fd = open("/dev/input/event1",O_RDWR );
if(fd < 0){
printf("Unable open /dev/input/event0\n");
return -1;
}
while(1){
if(read(fd, &ievent, sizeof(struct input_event)) < 0);
return -1;
if(ievent.type == EV_KEY){
switch(ievent.code){
case BTN_0:
ievent.value ? printf("key1 is pressed!\n"):printf("key1 is released!!\n");
break;
case BTN_1:
ievent.value ? printf("key2 is pressed!\n"):printf("key2 is released!!\n");
break;
case BTN_2:
ievent.value ? printf("key3 is pressed!\n"):printf("key3 is released!!\n");
break;
case BTN_3:
ievent.value ? printf("key4 is pressed!\n"):printf("key4 is released!!\n");
break;
case BTN_4:
ievent.value ? printf("key5 is pressed!\n"):printf("key5 is released!!\n");
break;
case BTN_5:
ievent.value ? printf("key6 is pressed!\n"):printf("key6 is released!!\n");
break;
case BTN_6:
ievent.value ? printf("key7 is pressed!\n"):printf("key7 is released!!\n");
break;
case BTN_7:
ievent.value ? printf("key8 is pressed!\n"):printf("key8 is released!!\n");
break;
}
}
}
close(fd);
return 0;
}