#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
浙公网安备 33010602011771号