static void buttons_irq(int irq, void *dev_id, struct pt_regs *reg) { struct key_info *k; int i; int found = 0; int up; int flags; for (i = 0; i < sizeof key_info_tab / sizeof key_info_tab[1]; i++) { k = key_info_tab + i; if (k->irq_no == irq) { found = 1; break; } } if (!found) { printk("bad irq %d in button\n", irq); return; } save_flags(flags); cli(); set_gpio_mode_user(k->gpio_port, GPIO_MODE_IN); up = read_gpio_bit(k->gpio_port); set_external_irq(k->irq_no, EXT_BOTH_EDGES, GPIO_PULLUP_DIS); restore_flags(flags); if (up) { key_value = k->key_no + 0x80; } else { key_value = k->key_no; } ready = 1; wake_up_interruptible(&buttons_wait); }
static int request_irqs(void) { struct key_info *k; int i; for (i = 0; i < sizeof key_info_tab / sizeof key_info_tab[1]; i++) { k = key_info_tab + i; set_external_irq(k->irq_no, EXT_BOTH_EDGES, GPIO_PULLUP_DIS); if (request_irq(k->irq_no, &buttons_irq, SA_INTERRUPT, DEVICE_NAME, &buttons_irq)) { return -1; } } return 0; }
static int __init s3c2410_kbd_init(void) { int ret; int oldiiccon; int flags; ret = set_external_irq(IRQ_KBD, EXT_FALLING_EDGE, GPIO_PULLUP_EN); local_irq_save(flags); IIC_init(); Set_IIC_mode(ZLG7289_IICCON, &oldiiccon); ret=IIC_Read(ZLG7290_ADDR, 0); //restore IICCON Set_IIC_mode(oldiiccon, NULL); local_irq_save(flags); DPRINTK("zlg7290 system register=0x%x\n", ret); KBD_CLOSE_INT(); ret = register_chrdev(0, DEVICE_NAME, &s3c2410_fops); if (ret < 0) { printk(DEVICE_NAME " can't get major number\n"); return ret; } kbdMajor = ret; /* Enable touch interrupt */ ret = request_irq(IRQ_KBD, s3c2410_isr_kbd,SA_INTERRUPT, DEVICE_NAME, s3c2410_isr_kbd); if (ret) { return ret; } kbddev.head = kbddev.tail = 0; kbddev.kbdmode= KEY_NULL; init_waitqueue_head(&(kbddev.wq)); #ifdef CONFIG_DEVFS_FS devfs_kbd_dir = devfs_mk_dir(NULL, "keyboard", NULL); devfs_kbdraw = devfs_register(devfs_kbd_dir, "0raw", DEVFS_FL_DEFAULT, kbdMajor, KBDRAW_MINOR, S_IFCHR | S_IRUSR | S_IWUSR, &s3c2410_fops, NULL); #endif printk (DEVICE_NAME"\tinitialized\n"); return 0; }