Example #1
0
static void pxa27x_keyboard_event (PXA2xxKeyPadState *kp, int keycode)
{
    int row, col,rel;

    if(!(kp->kpc & KPC_ME)) /* skip if not enabled */
        return;

    if(kp->kpc & KPC_AS || kp->kpc & KPC_ASACT) {
        if(kp->kpc & KPC_AS)
            kp->kpc &= ~(KPC_AS);

        rel = (keycode & 0x80) ? 1 : 0; /* key release from qemu */
        keycode &= ~(0x80); /* strip qemu key release bit */
        row = kp->map[keycode].row;
        col = kp->map[keycode].column;
        if(row == -1 || col == -1)
            return;
        switch (col) {
        case 0:
        case 1:
            if(rel)
                kp->kpasmkp0 = ~(0xffffffff);
            else
                kp->kpasmkp0 |= KPASMKPx_MKC(row,col);
            break;
        case 2:
        case 3:
            if(rel)
                kp->kpasmkp1 = ~(0xffffffff);
            else
                kp->kpasmkp1 |= KPASMKPx_MKC(row,col);
            break;
        case 4:
        case 5:
            if(rel)
                kp->kpasmkp2 = ~(0xffffffff);
            else
                kp->kpasmkp2 |= KPASMKPx_MKC(row,col);
            break;
        case 6:
        case 7:
            if(rel)
                kp->kpasmkp3 = ~(0xffffffff);
            else
                kp->kpasmkp3 |= KPASMKPx_MKC(row,col);
            break;
        } /* switch */
        goto out;
    }
    return;

out:
    if(kp->kpc & KPC_MIE) {
        kp->kpc |= KPC_MI;
        qemu_irq_raise(kp->irq);
    }
    return;
}
Example #2
0
static void pxa27x_keyboard_event (PXA2xxKeyPadState *kp, int keycode)
{
    int row, col, rel, assert_irq = 0;
    uint32_t val;

    if (keycode == 0xe0) {
        kp->alt_code = 1;
        return;
    }

    if(!(kp->kpc & KPC_ME)) /* skip if not enabled */
        return;

    rel = (keycode & 0x80) ? 1 : 0; /* key release from qemu */
    keycode &= ~0x80; /* strip qemu key release bit */
    if (kp->alt_code) {
        keycode |= 0x80;
        kp->alt_code = 0;
    }

    row = kp->map[keycode].row;
    col = kp->map[keycode].column;
    if (row == -1 || col == -1) {
        return;
    }

    val = KPASMKPx_MKC(row, col);
    if (rel) {
        if (kp->kpasmkp[col / 2] & val) {
            kp->kpasmkp[col / 2] &= ~val;
            kp->pressed_cnt--;
            assert_irq = 1;
        }
    } else {
        if (!(kp->kpasmkp[col / 2] & val)) {
            kp->kpasmkp[col / 2] |= val;
            kp->pressed_cnt++;
            assert_irq = 1;
        }
    }
    kp->kpas = ((kp->pressed_cnt & 0x1f) << 26) | (0xf << 4) | 0xf;
    if (kp->pressed_cnt == 1) {
        kp->kpas &= ~((0xf << 4) | 0xf);
        if (rel) {
            pxa27x_keypad_find_pressed_key(kp, &row, &col);
        }
        kp->kpas |= ((row & 0xf) << 4) | (col & 0xf);
    }

    if (!(kp->kpc & (KPC_AS | KPC_ASACT)))
        assert_irq = 0;

    if (assert_irq && (kp->kpc & KPC_MIE)) {
        kp->kpc |= KPC_MI;
        qemu_irq_raise(kp->irq);
    }
}
Example #3
0
static irqreturn_t pxakbd_irq_handler(int irq, void *dev_id)
{
	struct platform_device *pdev = dev_id;
	struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data;
	struct input_dev *input_dev = platform_get_drvdata(pdev);
	unsigned long kpc = KPC;
	int p, row, col, rel;

	if (kpc & KPC_DI) {
		unsigned long kpdk = KPDK;

		if (!(kpdk & KPDK_DKP)) {
			/* better luck next time */
		} else if (kpc & KPC_REE0) {
			unsigned long kprec = KPREC;
			KPREC = 0x7f;

			if (kprec & KPREC_OF0)
				rel = (kprec & 0xff) + 0x7f;
			else if (kprec & KPREC_UF0)
				rel = (kprec & 0xff) - 0x7f - 0xff;
			else
				rel = (kprec & 0xff) - 0x7f;

			if (rel) {
				input_report_rel(input_dev, REL_WHEEL, rel);
				input_sync(input_dev);
			}
		}
	}

	if (kpc & KPC_MI) {
		/* report the status of every button */
		for (row = 0; row < pdata->nr_rows; row++) {
			for (col = 0; col < pdata->nr_cols; col++) {
				p = KPASMKP(col) & KPASMKPx_MKC(row, col) ?
					1 : 0;
				pr_debug("keycode %x - pressed %x\n",
						pdata->keycodes[row][col], p);
				input_report_key(input_dev,
						pdata->keycodes[row][col], p);
			}
		}
		input_sync(input_dev);
	}

	return IRQ_HANDLED;
}