Ejemplo n.º 1
0
static int pmic8058_kp_scan_matrix(struct pmic8058_kp *kp, unsigned int events)
{
	u16 new_state[PM8058_MAX_ROWS];
	u16 old_state[PM8058_MAX_ROWS];
	int rc;

	switch (events) {
	case 0x1:
		rc = pmic8058_kp_read_matrix(kp, new_state, NULL);
		if (pmic8058_detect_ghost_keys(kp, new_state))
			return -EINVAL;
		__pmic8058_kp_scan_matrix(kp, new_state, kp->keystate);
		memcpy(kp->keystate, new_state, sizeof(new_state));
	break;
	case 0x3: /* two events - eventcounter is gray-coded */
		rc = pmic8058_kp_read_matrix(kp, new_state, old_state);
		__pmic8058_kp_scan_matrix(kp, old_state, kp->keystate);
		__pmic8058_kp_scan_matrix(kp, new_state, old_state);
		memcpy(kp->keystate, new_state, sizeof(new_state));
	break;
	case 0x2:
		dev_dbg(kp->dev, "Some key events are missed\n");
		rc = pmic8058_kp_read_matrix(kp, new_state, old_state);
		__pmic8058_kp_scan_matrix(kp, old_state, kp->keystate);
		__pmic8058_kp_scan_matrix(kp, new_state, old_state);
		memcpy(kp->keystate, new_state, sizeof(new_state));
	break;
	default:
		rc = -1;
	}
	return rc;
}
Ejemplo n.º 2
0
static int pmic8058_kp_scan_matrix(struct pmic8058_kp *kp, unsigned int events)
{
	u16 new_state[MATRIX_MAX_ROWS];
	u16 old_state[MATRIX_MAX_ROWS];
	int rc;

	dev_dbg(kp->dev, "events reported are %d\n", events);

	switch (events) {
	case 0x1:
		rc = pmic8058_kp_read_matrix(kp, new_state, NULL);
		__pmic8058_kp_scan_matrix(kp, new_state, kp->keystate);
		memcpy(kp->keystate, new_state, sizeof(new_state));
	break;
	case 0x3: /* two events - eventcounter is gray-coded */
		rc = pmic8058_kp_read_matrix(kp, new_state, old_state);
		__pmic8058_kp_scan_matrix(kp, old_state, kp->keystate);
		__pmic8058_kp_scan_matrix(kp, new_state, old_state);
		memcpy(kp->keystate, new_state, sizeof(new_state));
	break;
	case 0x2:
		dev_dbg(kp->dev, "Some key events are missed\n");
		rc = pmic8058_kp_read_matrix(kp, new_state, old_state);
		__pmic8058_kp_scan_matrix(kp, old_state, kp->keystate);
		__pmic8058_kp_scan_matrix(kp, new_state, old_state);
		memcpy(kp->keystate, new_state, sizeof(new_state));
	break;
	default:
		rc = -1;
	}
	return rc;
}
Ejemplo n.º 3
0
/*
 * NOTE: We are reading recent and old data registers blindly
 * whenever key-stuck interrupt happens, because events counter doesn't
 * get updated when this interrupt happens due to key stuck doesn't get
 * considered as key state change.
 *
 * We are not using old data register contents after they are being read
 * because it might report the key which was pressed before the key being stuck
 * as stuck key because it's pressed status is stored in the old data
 * register.
 */
static irqreturn_t pmic8058_kp_stuck_irq(int irq, void *data)
{
	u16 new_state[PM8058_MAX_ROWS];
	u16 old_state[PM8058_MAX_ROWS];
	int rc;
	struct pmic8058_kp *kp = data;

	rc = pmic8058_kp_read_matrix(kp, new_state, old_state);
	__pmic8058_kp_scan_matrix(kp, new_state, kp->stuckstate);

	return IRQ_HANDLED;
}
Ejemplo n.º 4
0
static int __pmic8058_kp_scan_matrix(struct pmic8058_kp *kp, u16 *new_state,
                                     u16 *old_state)
{
    int row, col, code;

#ifdef CONFIG_KEYBOARD_ZTE
    for (row = 0; row < KEYP_NUM_ROWS; row++) {
#else
    for (row = 0; row < kp->pdata->num_rows; row++) {
#endif
        int bits_changed = new_state[row] ^ old_state[row];

        if (!bits_changed)
            continue;

#ifdef CONFIG_KEYBOARD_ZTE
        for (col = 0; col < KEYP_NUM_COLS; col++) {
#else
        for (col = 0; col < kp->pdata->num_cols; col++) {
#endif
            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);
        }
    }

    return 0;
}

static int pmic8058_detect_ghost_keys(struct pmic8058_kp *kp, u16 *new_state)
{
    int row, found_first = -1;
    u16 check, row_state;

    check = 0;
    for (row = 0; row < kp->pdata->num_rows; row++) {
        row_state = (~new_state[row]) &
                    ((1 << kp->pdata->num_cols) - 1);

        if (hweight16(row_state) > 1) {
            if (found_first == -1)
                found_first = row;
            if (check & row_state) {
                dev_dbg(kp->dev, "detected ghost key on row[%d]"
                        "row[%d]\n", found_first, row);
                return 1;
            }
        }
        check |= row_state;
    }
    return 0;
}

static int pmic8058_kp_scan_matrix(struct pmic8058_kp *kp, unsigned int events)
{
    u16 new_state[PM8058_MAX_ROWS];
    u16 old_state[PM8058_MAX_ROWS];
    int rc;

    switch (events) {
    case 0x1:
        rc = pmic8058_kp_read_matrix(kp, new_state, NULL);
        if (pmic8058_detect_ghost_keys(kp, new_state))
            return -EINVAL;
        __pmic8058_kp_scan_matrix(kp, new_state, kp->keystate);
        memcpy(kp->keystate, new_state, sizeof(new_state));
        break;
    case 0x3: /* two events - eventcounter is gray-coded */
        rc = pmic8058_kp_read_matrix(kp, new_state, old_state);
        __pmic8058_kp_scan_matrix(kp, old_state, kp->keystate);
        __pmic8058_kp_scan_matrix(kp, new_state, old_state);
        memcpy(kp->keystate, new_state, sizeof(new_state));
        break;
    case 0x2:
        dev_dbg(kp->dev, "Some key events are missed\n");
        rc = pmic8058_kp_read_matrix(kp, new_state, old_state);
        __pmic8058_kp_scan_matrix(kp, old_state, kp->keystate);
        __pmic8058_kp_scan_matrix(kp, new_state, old_state);
        memcpy(kp->keystate, new_state, sizeof(new_state));
        break;
    default:
        rc = -1;
    }
    return rc;
}