static int __devinit pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) { int bits, rc, cycles; u8 scan_val = 0, ctrl_val = 0; static const u8 row_bits[] = { 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, }; /* Find column bits */ if (kp->pdata->num_cols < KEYP_CTRL_SCAN_COLS_MIN) bits = 0; else bits = kp->pdata->num_cols - KEYP_CTRL_SCAN_COLS_MIN; ctrl_val = (bits & KEYP_CTRL_SCAN_COLS_BITS) << KEYP_CTRL_SCAN_COLS_SHIFT; /* Find row bits */ if (kp->pdata->num_rows < KEYP_CTRL_SCAN_ROWS_MIN) bits = 0; else bits = row_bits[kp->pdata->num_rows - KEYP_CTRL_SCAN_ROWS_MIN]; ctrl_val |= (bits << KEYP_CTRL_SCAN_ROWS_SHIFT); rc = pmic8xxx_kp_write_u8(kp, ctrl_val, KEYP_CTRL); if (rc < 0) { dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc); return rc; } bits = (kp->pdata->debounce_ms / 5) - 1; scan_val |= (bits << KEYP_SCAN_DBOUNCE_SHIFT); bits = fls(kp->pdata->scan_delay_ms) - 1; scan_val |= (bits << KEYP_SCAN_PAUSE_SHIFT); /* Row hold time is a multiple of 32KHz cycles. */ cycles = (kp->pdata->row_hold_ns * KEYP_CLOCK_FREQ) / NSEC_PER_SEC; scan_val |= (cycles << KEYP_SCAN_ROW_HOLD_SHIFT); rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); if (rc) dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); return rc; }
static int pmic8xxx_kp_disable(struct pmic8xxx_kp *kp) { int rc; kp->ctrl_reg &= ~KEYP_CTRL_KEYP_EN; rc = pmic8xxx_kp_write_u8(kp, kp->ctrl_reg, KEYP_CTRL); if (rc < 0) return rc; return rc; }
static int pmic8xxx_kp_enable(struct pmic8xxx_kp *kp) { int rc; kp->ctrl_reg |= KEYP_CTRL_KEYP_EN; rc = pmic8xxx_kp_write_u8(kp, kp->ctrl_reg, KEYP_CTRL); if (rc < 0) dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc); return rc; }
static int pmic8xxx_kp_read_matrix(struct pmic8xxx_kp *kp, u16 *new_state, u16 *old_state) { int rc, read_rows; u8 scan_val; if (kp->pdata->num_rows < PM8XXX_MIN_ROWS) read_rows = PM8XXX_MIN_ROWS; else read_rows = kp->pdata->num_rows; pmic8xxx_chk_sync_read(kp); if (old_state) { rc = pmic8xxx_kp_read_data(kp, old_state, KEYP_OLD_DATA, read_rows); if (rc < 0) { dev_err(kp->dev, "Error reading KEYP_OLD_DATA, rc=%d\n", rc); return rc; } } rc = pmic8xxx_kp_read_data(kp, new_state, KEYP_RECENT_DATA, read_rows); if (rc < 0) { dev_err(kp->dev, "Error reading KEYP_RECENT_DATA, rc=%d\n", rc); return rc; } /* 4 * 32KHz clocks */ udelay((4 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1); rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN); if (rc < 0) { dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc); return rc; } scan_val &= 0xFE; rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); if (rc < 0) dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); return rc; }
/* * Synchronous read protocol for RevB0 onwards: * * 1. Write '1' to ReadState bit in KEYP_SCAN register * 2. Wait 2*32KHz clocks, so that HW can successfully enter read mode * synchronously * 3. Read rows in old array first if events are more than one * 4. Read rows in recent array * 5. Wait 4*32KHz clocks * 6. Write '0' to ReadState bit of KEYP_SCAN register so that hw can * synchronously exit read mode. */ static int pmic8xxx_chk_sync_read(struct pmic8xxx_kp *kp) { int rc; u8 scan_val; rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN); if (rc < 0) return rc; scan_val |= 0x1; rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); if (rc < 0) return rc; /* 2 * 32KHz clocks */ udelay((2 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1); return rc; }
/* * Synchronous read protocol for RevB0 onwards: * * 1. Write '1' to ReadState bit in KEYP_SCAN register * 2. Wait 2*32KHz clocks, so that HW can successfully enter read mode * synchronously * 3. Read rows in old array first if events are more than one * 4. Read rows in recent array * 5. Wait 4*32KHz clocks * 6. Write '0' to ReadState bit of KEYP_SCAN register so that hw can * synchronously exit read mode. */ static int pmic8xxx_chk_sync_read(struct pmic8xxx_kp *kp) { int rc; u8 scan_val; rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN); if (rc < 0) { dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc); return rc; } scan_val |= 0x1; rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); if (rc < 0) { dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); return rc; } /* 2 * 32KHz clocks */ udelay((2 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1); return rc; }
static int pmic8xxx_kp_read_matrix(struct pmic8xxx_kp *kp, u16 *new_state, u16 *old_state) { int rc, read_rows; u8 scan_val; #ifdef CONFIG_HUAWEI_KERNEL int i=0; #endif if (kp->pdata->num_rows < PM8XXX_MIN_ROWS) read_rows = PM8XXX_MIN_ROWS; else read_rows = kp->pdata->num_rows; pmic8xxx_chk_sync_read(kp); if (old_state) { rc = pmic8xxx_kp_read_data(kp, old_state, KEYP_OLD_DATA, read_rows); if (rc < 0) { dev_err(kp->dev, "Error reading KEYP_OLD_DATA, rc=%d\n", rc); return rc; } /*it is reslove the problem of ghost , becuse the six column just one key */ #ifdef CONFIG_HUAWEI_KERNEL if(machine_is_msm8255_u8730()) { if(~old_state[0] &(1<<(kp->pdata->num_cols-1))) { for(i=1;i< kp->pdata->num_rows;i++) { old_state[i] |= 1<<(kp->pdata->num_cols-1); } } } #endif } rc = pmic8xxx_kp_read_data(kp, new_state, KEYP_RECENT_DATA, read_rows); if (rc < 0) { dev_err(kp->dev, "Error reading KEYP_RECENT_DATA, rc=%d\n", rc); return rc; } /*it is reslove the problem of ghost , becuse the six column just one key */ #ifdef CONFIG_HUAWEI_KERNEL if(machine_is_msm8255_u8730()) { if(~new_state[0] &(1<<(kp->pdata->num_cols-1))) { for(i=1;i< kp->pdata->num_rows-1;i++) { new_state[i] |= 1<<(kp->pdata->num_cols-1); } } } #endif /* 4 * 32KHz clocks */ udelay((4 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1); rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN); if (rc < 0) { dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc); return rc; } scan_val &= 0xFE; rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); if (rc < 0) dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); return rc; }