static void twl4030_kp_scan(struct omap_keypad *kp, int release_all) { u16 new_state[MAX_ROWS]; int col, row; if (release_all) memset(new_state, 0, sizeof(new_state)); else { /* check for any changes */ int ret = omap_kp_read_kp_matrix_state(kp, new_state); if (ret < 0) /* panic ... */ return; if (omap_kp_is_in_ghost_state(kp, new_state)) return; } mutex_lock(&kp->mutex); /* check for changes and print those */ for (row = 0; row < kp->n_rows; row++) { int changed = new_state[row] ^ kp->kp_state[row]; if (!changed) continue; for (col = 0; col < kp->n_cols + 1; col++) { int key; if (!(changed & (1 << col))) continue; dev_dbg(kp->dbg_dev, "key [%d:%d] %s\n", row, col, (new_state[row] & (1 << col)) ? "press" : "release"); key = omap_kp_find_key(kp, col, row); if (key < 0) { #if defined(CONFIG_MACH_OMAP_LDP) || defined(CONFIG_MACH_OMAP_ZOOM2) /* OMAP LDP has a TWL4030 GPIO * (KBR5/KBC4) that is set to a persistent * state and should be ignored. */ if (row == 5 && col == 4) continue; #endif dev_warn(kp->dbg_dev, "Spurious key event %d-%d\n", col, row); } else input_report_key(kp->omap_twl4030kp, key, new_state[row] & (1 << col)); } kp->kp_state[row] = new_state[row]; } mutex_unlock(&kp->mutex); }
static void omap_kp_tasklet(unsigned long data) { unsigned char new_state[8], changed, key_down = 0; int col, row; int spurious = 0; /* check for any changes */ omap_kp_scan_keypad(new_state); /* check for changes and print those */ for (col = 0; col < 8; col++) { changed = new_state[col] ^ keypad_state[col]; key_down |= new_state[col]; if (changed == 0) continue; for (row = 0; row < 8; row++) { int key; if (!(changed & (1 << row))) continue; #ifdef NEW_BOARD_LEARNING_MODE printk(KERN_INFO "omap-keypad: key %d-%d %s\n", col, row, (new_state[col] & (1 << row)) ? "pressed" : "released"); #else key = omap_kp_find_key(col, row); if (key < 0) { printk(KERN_WARNING "omap-keypad: Spurious key event %d-%d\n", col, row); /* We scan again after a couple of seconds */ spurious = 1; continue; } input_report_key(&omap_kp_dev, key, new_state[col] & (1 << row)); #endif } } memcpy(keypad_state, new_state, sizeof(keypad_state)); if (key_down) { int delay = HZ / 20; /* some key is pressed - keep irq disabled and use timer * to poll the keypad */ if (spurious) delay = 2 * HZ; mod_timer(&kp_timer, jiffies + delay); } else { /* enable interrupts */ omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); } }
static void omap_kp_tasklet(unsigned long data) { struct omap_kp *omap_kp_data = (struct omap_kp *) data; unsigned char new_state[8], changed, key_down = 0; int col, row; int spurious = 0; /* check for any changes */ omap_kp_scan_keypad(omap_kp_data, new_state); /* check for changes and print those */ for (col = 0; col < omap_kp_data->cols; col++) { changed = new_state[col] ^ keypad_state[col]; key_down |= new_state[col]; if (changed == 0) continue; for (row = 0; row < omap_kp_data->rows; row++) { int key; if (!(changed & (1 << row))) continue; #ifdef NEW_BOARD_LEARNING_MODE printk(KERN_INFO "omap-keypad: key %d-%d %s\n", col, row, (new_state[col] & (1 << row)) ? "pressed" : "released"); #else key = omap_kp_find_key(col, row); if (key < 0) { printk(KERN_WARNING "omap-keypad: Spurious key event %d-%d\n", col, row); /* We scan again after a couple of seconds */ spurious = 1; continue; } if (!(kp_cur_group == (key & GROUP_MASK) || kp_cur_group == -1)) continue; kp_cur_group = key & GROUP_MASK; input_report_key(omap_kp_data->input, key & ~GROUP_MASK, new_state[col] & (1 << row)); #endif } } memcpy(keypad_state, new_state, sizeof(keypad_state)); if (key_down) { int delay = HZ / 20; /* some key is pressed - keep irq disabled and use timer * to poll the keypad */ if (spurious) delay = 2 * HZ; mod_timer(&omap_kp_data->timer, jiffies + delay); } else { /* enable interrupts */ if (cpu_is_omap24xx()) { int i; for (i = 0; i < omap_kp_data->rows; i++) enable_irq(gpio_to_irq(row_gpios[i])); } else { omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); kp_cur_group = -1; } } }
static void omap_kp_tasklet(unsigned long data) { struct omap_kp *omap_kp_data = (struct omap_kp *) data; unsigned char new_state[8], changed, key_down = 0; long irq = omap_kp_data->irq; int col, row; int spurious = 0; /* check for any changes */ omap_kp_scan_keypad(omap_kp_data, new_state); /* check for changes and print those */ for (col = 0; col < omap_kp_data->cols; col++) { changed = new_state[col] ^ keypad_state[col]; key_down |= new_state[col]; if (changed == 0) continue; for (row = 0; row < omap_kp_data->rows; row++) { int key; if (!(changed & (1 << row))) continue; #ifdef NEW_BOARD_LEARNING_MODE printk(KERN_INFO "[omap_kp:]omap-keypad: key %d-%d %s\n", col, row, (new_state[col] & (1 << row)) ? "pressed" : "released"); #else /* Keymappings have changed in omap4.*/ if (cpu_is_omap44xx()) key = omap_kp_find_key(row, col); else key = omap_kp_find_key(col, row); if (key < 0) { printk(KERN_WARNING "omap-keypad: Spurious key event %d-%d\n", col, row); /* We scan again after a couple of seconds */ spurious = 1; continue; } if (!(kp_cur_group == (key & GROUP_MASK) || kp_cur_group == -1)) continue; kp_cur_group = key & GROUP_MASK; input_report_key(omap_kp_data->input, key & ~GROUP_MASK, new_state[col] & (1 << row)); input_sync(omap_kp_data->input); #ifdef FACTORY_AT_COMMAND_GKPD if(test_mode == 1 && ((new_state[col] & (1 << row)) == 0)) { test_code = key & ~GROUP_MASK; write_gkpd_value(test_code); } #endif #endif } } memcpy(keypad_state, new_state, sizeof(keypad_state)); if (key_down) { int delay = HZ / 20; /* some key is pressed - keep irq disabled and use timer * to poll the keypad */ if (spurious) delay = 2 * HZ; mod_timer(&omap_kp_data->timer, jiffies + delay); } else { /* enable interrupts */ if (cpu_is_omap24xx()) { int i; for (i = 0; i < omap_kp_data->rows; i++) enable_irq(gpio_to_irq(row_gpios[i])); } else if (cpu_is_omap44xx()) { omap_writel(OMAP4_KBD_IRQENABLE_EVENTEN | OMAP4_KBD_IRQENABLE_LONGKEY, OMAP4_KBDOCP_BASE + OMAP4_KBD_IRQENABLE); kp_cur_group = -1; } else { omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); kp_cur_group = -1; } } enable_irq(irq); /* now clear any pending interrupts */ omap_writel(omap_readl(OMAP4_KBDOCP_BASE + OMAP4_KBD_IRQSTATUS), OMAP4_KBDOCP_BASE + OMAP4_KBD_IRQSTATUS); }