/* * Keypad interrupt handler */ static irqreturn_t do_kp_irq(int irq, void *_kp) { struct twl4030_keypad *kp = _kp; u8 reg; int ret; #ifdef CONFIG_LOCKDEP /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which * we don't want and can't tolerate. Although it might be * friendlier not to borrow this thread context... */ local_irq_enable(); #endif /* Read & Clear TWL4030 pending interrupt */ ret = twl4030_kpread(kp, ®, KEYP_ISR1, 1); /* Release all keys if I2C has gone bad or * the KEYP has gone to idle state */ if ((ret >= 0) && (reg & KEYP_IMR1_KP)) twl4030_kp_scan(kp, 0); else twl4030_kp_scan(kp, 1); return IRQ_HANDLED; }
static int twl4030_read_kp_matrix_state(struct twl4030_keypad *kp, u16 *state) { u8 new_state[MAX_ROWS]; int row; int ret = twl4030_kpread(kp, new_state, KEYP_FULL_CODE_7_0, kp->n_rows); if (ret >= 0) { for (row = 0; row < kp->n_rows; row++) state[row] = twl4030_col_xlate(kp, new_state[row]); } return ret; }
static int twl4030_kp_resume(struct platform_device * pdev) { int ret; u8 reg; struct twl4030_keypad *kp = platform_get_drvdata(pdev); ret = twl4030_kpread(kp, ®, KEYP_CTRL, 1); if (ret != 0) return -EIO; reg |= KEYP_CTRL_KBD_ON; ret = twl4030_kpwrite_u8(kp, reg, KEYP_CTRL); return ret; }
static int twl4030_kp_suspend(struct platform_device * pdev, pm_message_t state) { int ret; u8 reg; struct twl4030_keypad *kp = platform_get_drvdata(pdev); /* free the 32Khz clock and disable keypad */ ret = twl4030_kpread(kp, ®, KEYP_CTRL, 1); if (ret != 0) return -EIO; reg &= ~KEYP_CTRL_KBD_ON; ret = twl4030_kpwrite_u8(kp, reg, KEYP_CTRL); return ret; }