#include <linux/module.h>
    #include <linux/types.h>
    #include <linux/fs.h>
    #include <linux/errno.h>
    #include <linux/sched.h>
    #include <linux/init.h>
    #include <linux/cdev.h>
    #include <linux/device.h>
    #include <linux/gpio.h>
    #include <linux/mm.h>
    #include <linux/irq.h>
    #include <linux/interrupt.h>
    #include <asm/io.h>
    #include <asm/module.h>
    #include <asm/uaccess.h>
    #include <asm/irq.h>
    #include <mach/regs-gpio.h>
    #include <mach/hardware.h>
    #include <linux/input.h>

    struct input_dev *devp;

    struct key_irq_desc
    {
        int irq;
        int pin;
        int pin_value;
        int no;
        char *name;
    };

    static struct key_irq_desc key_irq_table[] =
    {
        {IRQ_EINT8 , S3C2410_GPG(0) , S3C2410_GPG0_EINT8 , 0, "KEY0"},
        {IRQ_EINT11, S3C2410_GPG(3) , S3C2410_GPG3_EINT11 , 1, "KEY1"},
        {IRQ_EINT13, S3C2410_GPG(5) , S3C2410_GPG5_EINT13 , 2, "KEY2"},
        {IRQ_EINT14, S3C2410_GPG(6) , S3C2410_GPG6_EINT14 , 3, "KEY3"},
        {IRQ_EINT15, S3C2410_GPG(7) , S3C2410_GPG7_EINT15 , 4, "KEY4"},
        {IRQ_EINT19, S3C2410_GPG(11), S3C2410_GPG11_EINT19, 5, "KEY5"},
    };

    static irqreturn_t s3c2440_key_interrupt(int irq, void *dev_id)
    {
        int i = *(int *)dev_id;
        if (!s3c2410_gpio_getpin(key_irq_table[i].pin))
        {
            switch(i)
            {
                case 0:
                    input_report_key(devp, KEY_0, 1);
                    break;
                case 1:
                    input_report_key(devp, KEY_1, 1);
                    break;
                case 2:
                    input_report_key(devp, KEY_2, 1);
                    break;
                case 3:
                    input_report_key(devp, KEY_3, 1);
                    break;
                case 4:
                    input_report_key(devp, KEY_4, 1);
                    break;
                case 5:
                    input_report_key(devp, KEY_5, 1);
                    break;
            }
            input_sync(devp);
        }
        return IRQ_RETVAL(IRQ_HANDLED);
    }
    static int s3c2440_key_setup_irq(void)
    {
        int i;
        for (i = 0; i < sizeof(key_irq_table)/sizeof(key_irq_table[0]); ++i)
        {
            if (key_irq_table[i].irq < 0)
                continue;
            if (request_irq(key_irq_table[i].irq, s3c2440_key_interrupt, IRQ_TYPE_EDGE_BOTH, key_irq_table[i].name, (void *)&key_irq_table[i].no))
            {
                printk(KERN_ERR "allocate irq fail%d\n", i);
                return -EBUSY;
            }
        }
        return 0;
    }

    static void s3c2440_key_free_irq(void)
    {
        int i;
        for (i = 0; i < sizeof(key_irq_table)/sizeof(key_irq_table[0]); ++i)
            free_irq(key_irq_table[i].irq, &key_irq_table[i].no);    
    }

    static int __init s3c2440_key_init(void)
    {
        int i, err;

        for (i = 0; i < sizeof(key_irq_table)/sizeof(key_irq_table[0]); ++i)
            s3c2410_gpio_setpin(key_irq_table[i].pin, key_irq_table[i].pin_value);
        if (s3c2440_key_setup_irq())
            return -EBUSY;
        devp = input_allocate_device();
        if (!devp)
        {
            printk(KERN_ERR "allocate input_dev fail!\n");
            err = -ENOMEM;
            goto fail_free_irq;
        }
        devp->name = "s3c2440_key_input";
        
        //set_bit(EV_KEY, devp->evbit);
        devp->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY);
        set_bit(KEY_0, devp->keybit);
        set_bit(KEY_1, devp->keybit);
        set_bit(KEY_2, devp->keybit);
        set_bit(KEY_3, devp->keybit);
        set_bit(KEY_4, devp->keybit);
        set_bit(KEY_5, devp->keybit);
        
        if ((err = input_register_device(devp)))
        {
            printk(KERN_ERR "register input_dev fail\n");
            goto fail_free_dev;
        }
        return 0;

    fail_free_dev:
        input_free_device(devp);
    fail_free_irq:
        s3c2440_key_free_irq();
        return err;
    }


    static void __exit s3c2440_key_exit(void)
    {
        input_unregister_device(devp);
        input_free_device(devp);
        s3c2440_key_free_irq();
    }


    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("Domod");
    module_init(s3c2440_key_init);
    module_exit(s3c2440_key_exit);

--app-key.c

点击(此处)折叠或打开

    #include "keydev.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/ioctl.h>
    #include <linux/input.h>


    int main(int argc, char **argv)
    {
        int count, i;
        int fd;
        struct input_event ev_key;
        fd = open("/dev/event1", 0);
        if (fd < 0)
        {
            perror("open device key!");
            exit(1);
        }
        while (1)
        {
            count = read(fd, &ev_key, sizeof(struct input_event));
            if (EV_KEY == ev_key.type)
                printf("type:%d,code:%d,value:%d\n", ev_key.type, ev_key.code, ev_key.value);
            if (EV_SYN == ev_key.type)
                printf("syn event\n");
        }
        close(fd);
        return 0;
    }

--Makefile

点击(此处)折叠或打开

    ifneq ($(KERNELRELEASE),)

    obj-m := key.o

    else
        
    KDIR := /home/domod/arm/kernel/src/linux-2.6.32.2
    all:
        make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
    app:
        arm-linux-gcc app-key.c -o key
    clean:
        rm -f *.ko *.o *.mod.o *.mod.c *.symvers modul*


    endif

 

posted on 2013-02-17 18:50  爱哎唉  阅读(342)  评论(0)    收藏  举报