static void tegra_kbc_report_keys(struct tegra_kbc *kbc) { unsigned char scancodes[KBC_MAX_KPENT]; unsigned short keycodes[KBC_MAX_KPENT]; u32 val = 0; unsigned int i; unsigned int num_down = 0; bool fn_keypress = false; bool key_in_same_row = false; bool key_in_same_col = false; for (i = 0; i < KBC_MAX_KPENT; i++) { if ((i % 4) == 0) val = readl(kbc->mmio + KBC_KP_ENT0_0 + i); if (val & 0x80) { unsigned int col = val & 0x07; unsigned int row = (val >> 3) & 0x0f; unsigned char scancode = MATRIX_SCAN_CODE(row, col, KBC_ROW_SHIFT); scancodes[num_down] = scancode; keycodes[num_down] = kbc->keycode[scancode]; /* If driver uses Fn map, do not report the Fn key. */ if ((keycodes[num_down] == KEY_FN) && kbc->use_fn_map) fn_keypress = true; else num_down++; } val >>= 8; }
static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state, u16 *old_state) { int row, col, code; for (row = 0; row < kp->pdata->num_rows; row++) { int bits_changed = new_state[row] ^ old_state[row]; if (!bits_changed) continue; for (col = 0; col < kp->pdata->num_cols; col++) { if (!(bits_changed & (1 << col))) continue; dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col, !(new_state[row] & (1 << col)) ? "pressed" : "released"); code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT); input_event(kp->input, EV_MSC, MSC_SCAN, code); input_report_key(kp->input, kp->keycodes[code], !(new_state[row] & (1 << col))); input_sync(kp->input); } } }
static void tca8418_read_keypad(struct tca8418_keypad *keypad_data) { struct input_dev *input = keypad_data->input; unsigned short *keymap = input->keycode; int error, col, row; u8 reg, state, code; /* Initial read of the key event FIFO */ error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®); /* Assume that key code 0 signifies empty FIFO */ while (error >= 0 && reg > 0) { state = reg & KEY_EVENT_VALUE; code = reg & KEY_EVENT_CODE; row = code / TCA8418_MAX_COLS; col = code % TCA8418_MAX_COLS; row = (col) ? row : row - 1; col = (col) ? col - 1 : TCA8418_MAX_COLS - 1; code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift); input_event(input, EV_MSC, MSC_SCAN, code); input_report_key(input, keymap[code], state); /* Read for next loop */ error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®); } if (error < 0) dev_err(&keypad_data->client->dev, "unable to read REG_KEY_EVENT_A\n"); input_sync(input); }
static int __stmpe1801_get_keycode_entries(u32 mask_row, u32 mask_col) { int col, row; int i, j, comp; row = mask_row & 0xff; col = mask_col & 0x3ff; for (i = 8; i > 0; i--) { comp = 1 << (i - 1); printk(" row: %d, comp: %d\n", row, comp); if (row & comp) break; } for (j = 10; j > 0; j--) { comp = 1 << (j - 1); printk(" col: %d, comp: %d\n", col, comp); if (col & comp) break; } #ifdef DBG_PRN printk(" row: %d, col: %d\n", i, j); #endif return (MATRIX_SCAN_CODE(i - 1, j - 1, STMPE1801_KPC_ROW_SHIFT)+1); }
static int __pmic8058_kp_scan_matrix(struct pmic8058_kp *kp, u16 *new_state, u16 *old_state) { int row, col, code; for (row = 0; row < kp->pdata->num_rows; row++) { int bits_changed = new_state[row] ^ old_state[row]; if (!bits_changed) continue; for (col = 0; col < kp->pdata->num_cols; col++) { if (!(bits_changed & (1 << col))) continue; dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col, !(new_state[row] & (1 << col)) ? "pressed" : "released"); printk("key [%d:%d] %s\n", row, col, !(new_state[row] & (1 << col)) ? "pressed" : "released"); // qiukj add for test code = MATRIX_SCAN_CODE(row, col, PM8058_ROW_SHIFT); input_event(kp->input, EV_MSC, MSC_SCAN, code); input_report_key(kp->input, kp->keycodes[code], !(new_state[row] & (1 << col))); printk("keypad [%s] keycode %d\n",__func__,kp->keycodes[code]); // qiukj add for test input_sync(kp->input); } } return 0; }
static void ske_keypad_report(struct ske_keypad *keypad, u8 status, int col) { int row = 0, code, pos; struct input_dev *input = keypad->input; u32 ske_ris; int key_pressed; int num_of_rows; /* find out the row */ num_of_rows = hweight8(status); do { pos = __ffs(status); row = pos; status &= ~(1 << pos); code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT); ske_ris = readl(keypad->reg_base + SKE_RIS); key_pressed = ske_ris & SKE_KPRISA; input_event(input, EV_MSC, MSC_SCAN, code); input_report_key(input, keypad->keymap[code], key_pressed); input_sync(input); num_of_rows--; } while (num_of_rows); }
static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state, u16 *old_state) { int row, col, code; for (row = 0; row < kp->pdata->num_rows; row++) { int bits_changed = new_state[row] ^ old_state[row]; if (!bits_changed) continue; for (col = 0; col < kp->pdata->num_cols; col++) { if (!(bits_changed & (1 << col))) continue; if (!col && !row) pm8xxx_tactickle_key_to_touch = 1; code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT); input_event(kp->input, EV_MSC, MSC_SCAN, code); input_report_key(kp->input, kp->keycodes[code], !(new_state[row] & (1 << col))); input_sync(kp->input); } } }
/****************************************************************************** * interrupt handler *****************************************************************************/ static irqreturn_t ftkbc010_interrupt(int irq, void *dev_id) { struct ftkbc010 *ftkbc010 = dev_id; struct input_dev *input = ftkbc010->input; unsigned int status; unsigned int cr; status = ioread32(ftkbc010->base + FTKBC010_OFFSET_ISR); /* * The clear interrupt bits are inside control register, * so we need to read it out and then modify it - * completely brain-dead design. */ cr = ioread32(ftkbc010->base + FTKBC010_OFFSET_CR); if (status & FTKBC010_ISR_RXINT) { dev_dbg(&input->dev, "RXINT\n"); cr |= FTKBC010_CR_CL_RXINT; } if (status & FTKBC010_ISR_TXINT) { dev_dbg(&input->dev, "TXINT\n"); cr |= FTKBC010_CR_CL_TXINT; } if (status & FTKBC010_ISR_PADINT) { unsigned int data; unsigned int row, col; unsigned int scancode; unsigned int keycode; data = ioread32(ftkbc010->base + FTKBC010_OFFSET_XC); col = ffs(0xff - FTKBC010_XC_L(data)) - 1; data = ioread32(ftkbc010->base + FTKBC010_OFFSET_YC); row = ffs(0xff - FTKBC010_YC_L(data)) - 1; scancode = MATRIX_SCAN_CODE(row, col, ftkbc010->row_shift); keycode = ftkbc010->keycode[scancode]; input_report_key(input, keycode, 1); input_sync(input); /* We cannot tell key release - simulate one */ input_report_key(input, keycode, 0); input_sync(input); dev_info(&input->dev, "(%x, %x) scancode %d, keycode %d\n", row, col, scancode, keycode); cr |= FTKBC010_CR_CL_PADINT; } iowrite32(cr, ftkbc010->base + FTKBC010_OFFSET_CR); return IRQ_HANDLED; }
/* * This gets the keys from keyboard and reports it to input subsystem */ static void matrix_keypad_scan(struct work_struct *work) { struct matrix_keypad *keypad = container_of(work, struct matrix_keypad, work.work); struct input_dev *input_dev = keypad->input_dev; const unsigned short *keycodes = input_dev->keycode; const struct matrix_keypad_platform_data *pdata = keypad->pdata; uint32_t new_state[MATRIX_MAX_COLS]; int row, col, code; /* de-activate all columns for scanning */ activate_all_cols(pdata, false); memset(new_state, 0, sizeof(new_state)); /* assert each column and read the row status out */ for (col = 0; col < pdata->num_col_gpios; col++) { activate_col(pdata, col, true); for (row = 0; row < pdata->num_row_gpios; row++) new_state[col] |= row_asserted(pdata, row) ? (1 << row) : 0; activate_col(pdata, col, false); } for (col = 0; col < pdata->num_col_gpios; col++) { uint32_t bits_changed; bits_changed = keypad->last_key_state[col] ^ new_state[col]; if (bits_changed == 0) continue; for (row = 0; row < pdata->num_row_gpios; row++) { if ((bits_changed & (1 << row)) == 0) continue; code = MATRIX_SCAN_CODE(row, col, keypad->row_shift); input_event(input_dev, EV_MSC, MSC_SCAN, code); input_report_key(input_dev, keycodes[code], new_state[col] & (1 << row)); } } input_sync(input_dev); memcpy(keypad->last_key_state, new_state, sizeof(new_state)); activate_all_cols(pdata, true); /* Enable IRQs again */ spin_lock_irq(&keypad->lock); keypad->scan_pending = false; enable_row_irqs(keypad); spin_unlock_irq(&keypad->lock); }
static void omap_kp_tasklet(unsigned long data) { struct omap_kp *omap_kp_data = (struct omap_kp *) data; unsigned short *keycodes = omap_kp_data->input->keycode; unsigned int row_shift = get_count_order(omap_kp_data->cols); 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 = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; 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 } } input_sync(omap_kp_data->input); 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 */ omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); kp_cur_group = -1; } }
static int __pmic8058_kp_scan_matrix(struct pmic8058_kp *kp, u16 *new_state, u16 *old_state) { int row, col, code; for (row = 0; row < kp->pdata->num_rows; row++) { int bits_changed = new_state[row] ^ old_state[row]; if (!bits_changed) continue; for (col = 0; col < kp->pdata->num_cols; col++) { if (!(bits_changed & (1 << col))) continue; dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col, !(new_state[row] & (1 << col)) ? "pressed" : "released"); code = MATRIX_SCAN_CODE(row, col, PM8058_ROW_SHIFT); input_event(kp->input, EV_MSC, MSC_SCAN, code); input_report_key(kp->input, kp->keycodes[code], !(new_state[row] & (1 << col))); input_sync(kp->input); #if defined (CONFIG_TARGET_LOCALE_USA) pr_info("key [%d:%d] %s\n", row, col, !(new_state[row] & (1 << col)) ? "pressed" : "released"); #else pr_info("key [%d:%d] %s keycode [%d]\n", row, col, !(new_state[row] & (1 << col)) ? "pressed" : "released", kp->keycodes[code]); #endif #if defined (CONFIG_TOUCHSCREEN_MELFAS) #if defined (CONFIG_KOR_MODEL_SHV_E120L) || defined (CONFIG_KOR_MODEL_SHV_E120S) || defined (CONFIG_KOR_MODEL_SHV_E120K) || defined(CONFIG_KOR_MODEL_SHV_E160S) || defined(CONFIG_KOR_MODEL_SHV_E160K) || defined(CONFIG_KOR_MODEL_SHV_E160L) if(!(new_state[row] & (1 << col)) && (kp->keycodes[code] == KEY_HOME)){ TSP_force_released(); } #endif #endif #if defined(CONFIG_SEC_DEBUG) sec_debug_check_crash_key(kp->keycodes[code], !(new_state[row] & (1 << col))); #endif } } return 0; }
static int check_key_down(struct sci_keypad_t *sci_kpd, int key_status, int key_value) { int col, row, key; unsigned short *keycodes = sci_kpd->input_dev->keycode; unsigned int row_shift = get_count_order(sci_kpd->cols); if((key_status & 0xff) != 0) { col = KPD_INT0_COL(key_status); row = KPD_INT0_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; if(key == key_value) return 1; } if((key_status & 0xff00) != 0) { col = KPD_INT1_COL(key_status); row = KPD_INT1_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; if(key == key_value) return 1; } return 0; }
//LGE_CHANGE_E:<*****@*****.**><03/06/2012><Slate feature porting from LS840 GB> static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state, u16 *old_state) { int row, col, code; for (row = 0; row < kp->pdata->num_rows; row++) { int bits_changed = new_state[row] ^ old_state[row]; if (!bits_changed) continue; for (col = 0; col < kp->pdata->num_cols; col++) { if (!(bits_changed & (1 << col))) continue; dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col, !(new_state[row] & (1 << col)) ? "pressed" : "released"); code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT); input_event(kp->input, EV_MSC, MSC_SCAN, code); #if defined (CONFIG_MACH_LGE_C1_BOARD_SPR) if(lgf_key_lock != 0x55){ #endif input_report_key(kp->input, kp->keycodes[code], !(new_state[row] & (1 << col))); input_sync(kp->input); //LGE_CHANGE_S:<*****@*****.**><03/06/2012><Slate feature porting from LS840 GB> // LGE_CHANGE_S [[email protected]] [2011.10.21] [CAYMAN] enable or disable key logging status of slate [START] #if defined (CONFIG_MACH_LGE_C1_BOARD_SPR) #ifdef CONFIG_LGE_DIAG_ICD if(key_touch_logging_status == 1) { printk(KERN_INFO "%s(), key_touch_logging_status 1 start key logging \n",__func__); if(key_logging_count == 0) slate_send_key_log_packet((unsigned long)kp->keycodes[code], (unsigned long)!col); key_logging_count++; if(key_logging_count > 1) key_logging_count = 0; } #endif // LGE_CHANGE_E [[email protected]] [2011.10.21] [CAYMAN] enable or disable key logging status of slate [END] //LGE_CHANGE_E:<*****@*****.**><03/06/2012><Slate feature porting from LS840 GB> } #endif } } }
static void stmpe1601_message_read(void) { u8 val, data, key_fifo[STMPE1601_KPC_DATA_LEN]; int row, col, kcode; bool up; int slide_state; int i, ret; /* Key LED ON */ if (!key_led_stat) { slide_state = gpio_get_value(KEYPAD_SLIDE_SW); if (slide_state) { key_led_onoff(true); key_led_stat = true; } } /* Key Read */ val = stmpe1601_read(gkpad, STMPE1601_REG_INT_STA_LSB); if (val & STPME1601_KPC_FIFO_OVR_EN) dev_err(&gkpad->i2c->dev, "[Q-KEY] Keypad FIFO Overflow\n"); if (val & STPME1601_KPC_INT_EN) { ret = stmpe1601_kpad_read_data(gkpad, key_fifo); if (ret < 0) dev_err(&gkpad->i2c->dev, "[Q-KEY] Keypad data read failed\n"); for (i = 0; i < STMPE1601_KPC_DATA_LEN-2; i++) { data = key_fifo[i]; row = (data & STMPE1601_KPC_DATA_ROW) >> 3; col = data & STMPE1601_KPC_DATA_COL; kcode = MATRIX_SCAN_CODE(row, col, STMPE1601_KPAD_ROW_SHIFT); up = data & STMPE1601_KPC_DATA_UP; keypress = up; if ((data & STMPE1601_KPC_DATA_NOKEY_MASK) == STMPE1601_KPC_DATA_NOKEY_MASK) continue; #if 0 dprintk(KERN_DEBUG"[Q-KEY] Row = %d, Col = %d, UP = %d\n", row, col, up); #else printk(KERN_ERR"[Q-KEY] code:%d, row=%d, col=%d, up=%d\n", gkpad->keycode[kcode], row, col, up); #endif input_event(gkpad->input, EV_MSC, MSC_SCAN, kcode); input_report_key(gkpad->input, gkpad->keycode[kcode], !up); input_sync(gkpad->input); } }
static void db5500_gpio_release_work(struct work_struct *work) { int code; struct db5500_keypad *keypad = container_of(work, struct db5500_keypad, gpio_work.work); struct input_dev *input = keypad->input; code = MATRIX_SCAN_CODE(keypad->gpio_col, keypad->gpio_row, KEYPAD_ROW_SHIFT); input_event(input, EV_MSC, MSC_SCAN, code); input_report_key(input, keypad->keymap[code], 1); input_sync(input); input_report_key(input, keypad->keymap[code], 0); input_sync(input); }
/* Interrupt handler */ static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) { struct omap4_keypad *keypad_data = dev_id; struct input_dev *input_dev = keypad_data->input; unsigned char key_state[ARRAY_SIZE(keypad_data->key_state)]; unsigned int col, row, code, changed; u32 *new_state = (u32 *) key_state; /* Disable interrupts */ __raw_writel(OMAP4_VAL_IRQDISABLE, keypad_data->base + OMAP4_KBD_IRQENABLE); *new_state = __raw_readl(keypad_data->base + OMAP4_KBD_FULLCODE31_0); *(new_state + 1) = __raw_readl(keypad_data->base + OMAP4_KBD_FULLCODE63_32); for (row = 0; row < keypad_data->rows; row++) { changed = key_state[row] ^ keypad_data->key_state[row]; if (!changed) continue; for (col = 0; col < keypad_data->cols; col++) { if (changed & (1 << col)) { code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift); input_event(input_dev, EV_MSC, MSC_SCAN, code); input_report_key(input_dev, keypad_data->keymap[code], key_state[row] & (1 << col)); } } } input_sync(input_dev); memcpy(keypad_data->key_state, key_state, sizeof(keypad_data->key_state)); /* clear pending interrupts */ __raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS), keypad_data->base + OMAP4_KBD_IRQSTATUS); /* enable interrupts */ __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY, keypad_data->base + OMAP4_KBD_IRQENABLE); return IRQ_HANDLED; }
static void w90p910_keypad_scan_matrix(struct w90p910_keypad *keypad, unsigned int status) { struct input_dev *input_dev = keypad->input_dev; unsigned int row = KGET_RAW(status); unsigned int col = KGET_COLUMN(status); unsigned int code = MATRIX_SCAN_CODE(row, col, W90P910_ROW_SHIFT); unsigned int key = keypad->keymap[code]; input_event(input_dev, EV_MSC, MSC_SCAN, code); input_report_key(input_dev, key, 1); input_sync(input_dev); input_event(input_dev, EV_MSC, MSC_SCAN, code); input_report_key(input_dev, key, 0); input_sync(input_dev); }
/* * Compares the new keyboard state to the old one and produces key * press/release events accordingly. The keyboard state is 13 bytes (one byte * per column) */ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, uint8_t *kb_state, int len) { struct input_dev *idev = ckdev->idev; struct cros_ec_device *ec = ckdev->ec; int col, row; int new_state; int old_state; int num_cols; num_cols = len; if (ckdev->ghost_filter && cros_ec_keyb_has_ghosting(ckdev, kb_state)) { /* * Simple-minded solution: ignore this state. The obvious * improvement is to only ignore changes to keys involved in * the ghosting, but process the other changes. */ dev_dbg(ckdev->dev, "ghosting found\n"); return; } for (col = 0; col < ckdev->cols; col++) { for (row = 0; row < ckdev->rows; row++) { int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift); const unsigned short *keycodes = idev->keycode; int code; code = keycodes[pos]; new_state = kb_state[col] & (1 << row); old_state = ckdev->old_kb_state[col] & (1 << row); if (new_state != old_state) { dev_dbg(ckdev->dev, "changed: [r%d c%d]: byte %02x\n", row, col, new_state); /* Change to power supply status */ if ((ec->charger && code == KEY_BATTERY)) { power_supply_changed(ec->charger); continue; } input_report_key(idev, code, new_state); } } ckdev->old_kb_state[col] = kb_state[col]; } input_sync(ckdev->idev); }
/** * db5500_keypad_report() - reports the keypad event * @keypad: pointer to device structure * @row: row value of keypad * @curr: current event * @previous: previous event * * This function uses to reports the event of the keypad * and returns NONE. * * By default all column reads are 1111 1111b. Any press will pull the column * down, leading to a 0 in any of these locations. We invert these values so * that a 1 means means "column pressed". * * If curr changes from the previous from 0 to 1, we report it as a key press. * If curr changes from the previous from 1 to 0, we report it as a key * release. */ static void db5500_keypad_report(struct db5500_keypad *keypad, int row, u8 curr, u8 previous) { struct input_dev *input = keypad->input; u8 changed = curr ^ previous; while (changed) { int col = __ffs(changed); bool press = curr & BIT(col); int code = MATRIX_SCAN_CODE(row, col, KEYPAD_ROW_SHIFT); input_event(input, EV_MSC, MSC_SCAN, code); input_report_key(input, keypad->keymap[code], press); input_sync(input); changed &= ~BIT(col); } }
/* * Walks keycodes flipping bit in buffer COLUMNS deep where bit is ROW. Used by * ghosting logic to ignore NULL or virtual keys. */ static void cros_ec_keyb_compute_valid_keys(struct cros_ec_keyb *ckdev) { int row, col; int row_shift = ckdev->row_shift; unsigned short *keymap = ckdev->idev->keycode; unsigned short code; BUG_ON(ckdev->idev->keycodesize != sizeof(*keymap)); for (col = 0; col < ckdev->cols; col++) { for (row = 0; row < ckdev->rows; row++) { code = keymap[MATRIX_SCAN_CODE(row, col, row_shift)]; if (code && (code != KEY_BATTERY)) ckdev->valid_keys[col] |= 1 << row; } dev_dbg(ckdev->dev, "valid_keys[%02d] = 0x%02x\n", col, ckdev->valid_keys[col]); } }
static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state, u16 *old_state) { int row, col, code; for (row = 0; row < kp->pdata->num_rows; row++) { int bits_changed = new_state[row] ^ old_state[row]; if (!bits_changed) continue; for (col = 0; col < kp->pdata->num_cols; col++) { if (!(bits_changed & (1 << col))) continue; dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col, !(new_state[row] & (1 << col)) ? "pressed" : "released"); code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT); input_event(kp->input, EV_MSC, MSC_SCAN, code); input_report_key(kp->input, kp->keycodes[code], !(new_state[row] & (1 << col))); input_sync(kp->input); #if defined (DSEC_KEYBOARD_CODE_DEBUG) pr_info("key [%d:%d] %s keycode [%d]\n", row, col, !(new_state[row] & (1 << col)) ? "pressed" : "released", kp->keycodes[code]); #else pr_info("key %s\n", !(new_state[row] & (1 << col)) ? "pressed" : "released"); #endif #if defined(CONFIG_SEC_DEBUG) sec_debug_check_crash_key(kp->keycodes[code], !(new_state[row] & (1 << col))); #endif } } }
static int __pmic8058_kp_scan_matrix(struct pmic8058_kp *kp, u16 *new_state, u16 *old_state) { int row, col, code; for (row = 0; row < kp->pdata->num_rows; row++) { int bits_changed = new_state[row] ^ old_state[row]; if (!bits_changed) continue; for (col = 0; col < kp->pdata->num_cols; col++) { if (!(bits_changed & (1 << col))) continue; dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col, !(new_state[row] & (1 << col)) ? "pressed" : "released"); code = MATRIX_SCAN_CODE(row, col, PM8058_ROW_SHIFT); /* in order to avoid reporting unvalid codes to input system, we should check the key's value not the index */ /* report the event only if the key is in the map. */ #ifdef CONFIG_HUAWEI_KERNEL if (kp->keycodes[code]) { #endif input_event(kp->input, EV_MSC, MSC_SCAN, code); input_report_key(kp->input, kp->keycodes[code], !(new_state[row] & (1 << col))); input_sync(kp->input); #ifdef CONFIG_HUAWEI_KERNEL } #endif } } return 0; }
static bool matrix_keypad_map_key(struct input_dev *input_dev, unsigned int rows, unsigned int cols, unsigned int row_shift, unsigned int key) { unsigned short *keymap = input_dev->keycode; unsigned int row = KEY_ROW(key); unsigned int col = KEY_COL(key); unsigned short code = KEY_VAL(key); if (row >= rows || col >= cols) { dev_err(input_dev->dev.parent, "%s: invalid keymap entry 0x%x (row: %d, col: %d, rows: %d, cols: %d)\n", __func__, key, row, col, rows, cols); return false; } keymap[MATRIX_SCAN_CODE(row, col, row_shift)] = code; __set_bit(code, input_dev->keybit); return true; }
static void ske_keypad_read_data(struct ske_keypad *keypad) { struct input_dev *input = keypad->input; u16 status; int col = 0, row = 0, code; int ske_asr, ske_ris, key_pressed, i; /* * Read the auto scan registers * * Each SKE_ASRx (x=0 to x=3) contains two row values. * lower byte contains row value for column 2*x, * upper byte contains row value for column 2*x + 1 */ for (i = 0; i < SKE_NUM_ASRX_REGISTERS; i++) { ske_asr = readl(keypad->reg_base + SKE_ASR0 + (4 * i)); if (!ske_asr) continue; /* now that ASRx is zero, find out the column x and row y*/ if (ske_asr & 0xff) { col = i * 2; status = ske_asr & 0xff; } else { col = (i * 2) + 1; status = (ske_asr & 0xff00) >> 8; } /* find out the row */ row = __ffs(status); code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT); ske_ris = readl(keypad->reg_base + SKE_RIS); key_pressed = ske_ris & SKE_KPRISA; input_event(input, EV_MSC, MSC_SCAN, code); input_report_key(input, keypad->keymap[code], key_pressed); input_sync(input); } }
static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state, u16 *old_state) { int row, col, code; for (row = 0; row < kp->pdata->num_rows; row++) { int bits_changed = new_state[row] ^ old_state[row]; if (!bits_changed) continue; for (col = 0; col < kp->pdata->num_cols; col++) { if (!(bits_changed & (1 << col))) continue; dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col, !(new_state[row] & (1 << col)) ? "pressed" : "released"); #if defined(CONFIG_MACH_APQ8064_GKKT)||defined(CONFIG_MACH_APQ8064_GKU) || defined(CONFIG_MACH_APQ8064_GKSK) if(!row && !col) pr_info("[key] Volume Down %s\n",!(new_state[row] & (1 << col)) ? "pressed" : "released"); else if(!row && col) pr_info("[key] Volume Up %s\n",!(new_state[row] & (1 << col)) ? "pressed" : "released"); else if(row && !col) pr_info("[key] Quick Memo %s\n",!(new_state[row] & (1 << col)) ? "pressed" : "released"); else pr_info("[key] Home %s\n",!(new_state[row] & (1 << col)) ? "pressed" : "released"); #endif code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT); input_event(kp->input, EV_MSC, MSC_SCAN, code); input_report_key(kp->input, kp->keycodes[code], !(new_state[row] & (1 << col))); input_sync(kp->input); } } }
/* Update the new_keycode_state*/ static void k3v2_keypad_update_keycode(struct k3v2_keypad *keypad, unsigned char *new_scancode_state, uint16_t *new_keycode_state) { int row = 0; int col = 0; int r = 0; int c = 0; int index = 0; uint8_t keycode = 0; for (row = 0; row < KPC_MAX_ROWS; row++) { for (col = 0; col < KPC_MAX_COLS; col++) { if (new_scancode_state[row] & (1 << col)) { index = MATRIX_SCAN_CODE(row, col, keypad->row_shift); keycode = keypad->keycodes[index]; c = keycode & 0x0F; r = keycode >> 4; new_keycode_state[r] |= (1 << c); } } }
static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state, u16 *old_state) { int row, col, code; for (row = 0; row < kp->pdata->num_rows; row++) { int bits_changed = new_state[row] ^ old_state[row]; if (!bits_changed) continue; for (col = 0; col < kp->pdata->num_cols; col++) { if (!(bits_changed & (1 << col))) continue; dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col, !(new_state[row] & (1 << col)) ? "pressed" : "released"); code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT); /*reduce invalid input event*/ #ifdef CONFIG_HUAWEI_KERNEL if (kp->keycodes[code]) { #endif input_event(kp->input, EV_MSC, MSC_SCAN, code); input_report_key(kp->input, kp->keycodes[code], !(new_state[row] & (1 << col))); /* use mmi_keystate save the key state */ mmi_keystate[kp->keycodes[code]] = (!(new_state[row]&(1<<col)))? MMI_KEY_DOWN :MMI_KEY_UP ; input_sync(kp->input); #ifdef CONFIG_HUAWEI_KERNEL } #endif } } }
static bool samsung_keypad_report(struct samsung_keypad *keypad, unsigned int *row_state) { struct input_dev *input_dev = keypad->input_dev; unsigned int changed; unsigned int pressed; unsigned int key_down = 0; unsigned int val; unsigned int col, row; for (col = 0; col < keypad->cols; col++) { changed = row_state[col] ^ keypad->row_state[col]; key_down |= row_state[col]; if (!changed) continue; for (row = 0; row < keypad->rows; row++) { if (!(changed & (1 << row))) continue; pressed = row_state[col] & (1 << row); dev_dbg(&keypad->input_dev->dev, "key %s, row: %d, col: %d\n", pressed ? "pressed" : "released", row, col); val = MATRIX_SCAN_CODE(row, col, keypad->row_shift); input_event(input_dev, EV_MSC, MSC_SCAN, val); input_report_key(input_dev, keypad->keycodes[val], pressed); } input_sync(keypad->input_dev); } memcpy(keypad->row_state, row_state, sizeof(keypad->row_state)); return key_down; }
static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state, u16 *old_state) { int row, col, code; for (row = 0; row < kp->pdata->num_rows; row++) { int bits_changed = new_state[row] ^ old_state[row]; if (!bits_changed) continue; for (col = 0; col < kp->pdata->num_cols; col++) { if (!(bits_changed & (1 << col))) continue; #if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP) dev_err(kp->dev, "key [%d:%d] %s\n", row, col, !(new_state[row] & (1 << col)) ? "pressed" : "released"); #endif #if defined(CONFIG_MACH_KS02) if(!(new_state[row] & (1 << col))) key_state = 1; else key_state = 0; #endif code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT); input_event(kp->input, EV_MSC, MSC_SCAN, code); input_report_key(kp->input, kp->keycodes[code], !(new_state[row] & (1 << col))); input_sync(kp->input); } } }
/* * Compare the new matrix state (volatile) with the stable one stored in * keypad->matrix_stable_state and fire events if changes are detected. */ static void imx_keypad_fire_events(struct imx_keypad *keypad, unsigned short *matrix_volatile_state) { struct input_dev *input_dev = keypad->input_dev; int row, col; for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) { unsigned short bits_changed; int code; if ((keypad->cols_en_mask & (1 << col)) == 0) continue; /* Column is not enabled */ bits_changed = keypad->matrix_stable_state[col] ^ matrix_volatile_state[col]; if (bits_changed == 0) continue; /* Column does not contain changes */ for (row = 0; row < MAX_MATRIX_KEY_ROWS; row++) { if ((keypad->rows_en_mask & (1 << row)) == 0) continue; /* Row is not enabled */ if ((bits_changed & (1 << row)) == 0) continue; /* Row does not contain changes */ code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT); input_event(input_dev, EV_MSC, MSC_SCAN, code); input_report_key(input_dev, keypad->keycodes[code], matrix_volatile_state[col] & (1 << row)); dev_dbg(&input_dev->dev, "Event code: %d, val: %d", keypad->keycodes[code], matrix_volatile_state[col] & (1 << row)); } } input_sync(input_dev); }