/*
 * (C) Copyright 2002 ELTEC Elektronik AG
 * Frank Gottschling <fgottschling@eltec.de>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/* i8042.c - Intel 8042 keyboard driver routines */

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <i8042.h>
#include <input.h>
#include <keyboard.h>
#include <asm/io.h>

DECLARE_GLOBAL_DATA_PTR;

/* defines */
#define in8(p)		inb(p)
#define out8(p, v)	outb(v, p)

enum {
	QUIRK_DUP_POR	= 1 << 0,
};

/* locals */
struct i8042_kbd_priv {
	bool extended;	/* true if an extended keycode is expected next */
	int quirks;	/* quirks that we support */
};

static unsigned char ext_key_map[] = {
	0x1c, /* keypad enter */
	0x1d, /* right control */
	0x35, /* keypad slash */
	0x37, /* print screen */
	0x38, /* right alt */
	0x46, /* break */
	0x47, /* editpad home */
	0x48, /* editpad up */
	0x49, /* editpad pgup */
	0x4b, /* editpad left */
	0x4d, /* editpad right */
	0x4f, /* editpad end */
	0x50, /* editpad dn */
	0x51, /* editpad pgdn */
	0x52, /* editpad ins */
	0x53, /* editpad del */
	0x00  /* map end */
	};

static int kbd_input_empty(void)
{
	int kbd_timeout = KBD_TIMEOUT * 1000;

	while ((in8(I8042_STS_REG) & STATUS_IBF) && kbd_timeout--)
		udelay(1);

	return kbd_timeout != -1;
}

static int kbd_output_full(void)
{
	int kbd_timeout = KBD_TIMEOUT * 1000;

	while (((in8(I8042_STS_REG) & STATUS_OBF) == 0) && kbd_timeout--)
		udelay(1);

	return kbd_timeout != -1;
}

/**
 * check_leds() - Check the keyboard LEDs and update them it needed
 *
 * @ret:	Value to return
 * @return value of @ret
 */
static int i8042_kbd_update_leds(struct udevice *dev, int leds)
{
	kbd_input_empty();
	out8(I8042_DATA_REG, CMD_SET_KBD_LED);
	kbd_input_empty();
	out8(I8042_DATA_REG, leds & 0x7);

	return 0;
}

static int kbd_write(int reg, int value)
{
	if (!kbd_input_empty())
		return -1;
	out8(reg, value);

	return 0;
}

static int kbd_read(int reg)
{
	if (!kbd_output_full())
		return -1;

	return in8(reg);
}

static int kbd_cmd_read(int cmd)
{
	if (kbd_write(I8042_CMD_REG, cmd))
		return -1;

	return kbd_read(I8042_DATA_REG);
}

static int kbd_cmd_write(int cmd, int data)
{
	if (kbd_write(I8042_CMD_REG, cmd))
		return -1;

	return kbd_write(I8042_DATA_REG, data);
}

static int kbd_reset(int quirk)
{
	int config;

	/* controller self test */
	if (kbd_cmd_read(CMD_SELF_TEST) != KBC_TEST_OK)
		goto err;

	/* keyboard reset */
	if (kbd_write(I8042_DATA_REG, CMD_RESET_KBD) ||
	    kbd_read(I8042_DATA_REG) != KBD_ACK ||
	    kbd_read(I8042_DATA_REG) != KBD_POR)
		goto err;

	if (kbd_write(I8042_DATA_REG, CMD_DRAIN_OUTPUT) ||
	    kbd_read(I8042_DATA_REG) != KBD_ACK)
		goto err;

	/* set AT translation and disable irq */
	config = kbd_cmd_read(CMD_RD_CONFIG);
	if (config == -1)
		goto err;

	/* Sometimes get a second byte */
	else if ((quirk & QUIRK_DUP_POR) && config == KBD_POR)
		config = kbd_cmd_read(CMD_RD_CONFIG);

	config |= CONFIG_AT_TRANS;
	config &= ~(CONFIG_KIRQ_EN | CONFIG_MIRQ_EN);
	if (kbd_cmd_write(CMD_WR_CONFIG, config))
		goto err;

	/* enable keyboard */
	if (kbd_write(I8042_CMD_REG, CMD_KBD_EN) ||
	    !kbd_input_empty())
		goto err;

	return 0;
err:
	debug("%s: Keyboard failure\n", __func__);
	return -1;
}

static int kbd_controller_present(void)
{
	return in8(I8042_STS_REG) != 0xff;
}

/*
 * Implement a weak default function for boards that optionally
 * need to skip the i8042 initialization.
 *
 * TODO(sjg@chromium.org): Use device tree for this?
 */
int __weak board_i8042_skip(void)
{
	/* As default, don't skip */
	return 0;
}

void i8042_flush(void)
{
	int timeout;

	/*
	 * The delay is to give the keyboard controller some time
	 * to fill the next byte.
	 */
	while (1) {
		timeout = 100;	/* wait for no longer than 100us */
		while (timeout > 0 && !(in8(I8042_STS_REG) & STATUS_OBF)) {
			udelay(1);
			timeout--;
		}

		/* Try to pull next byte if not timeout */
		if (in8(I8042_STS_REG) & STATUS_OBF)
			in8(I8042_DATA_REG);
		else
			break;
	}
}

int i8042_disable(void)
{
	if (kbd_input_empty() == 0)
		return -1;

	/* Disable keyboard */
	out8(I8042_CMD_REG, CMD_KBD_DIS);

	if (kbd_input_empty() == 0)
		return -1;

	return 0;
}

static int i8042_kbd_check(struct input_config *input)
{
	struct i8042_kbd_priv *priv = dev_get_priv(input->dev);

	if ((in8(I8042_STS_REG) & STATUS_OBF) == 0) {
		return 0;
	} else {
		bool release = false;
		int scan_code;
		int i;

		scan_code = in8(I8042_DATA_REG);
		if (scan_code == 0xfa) {
			return 0;
		} else if (scan_code == 0xe0) {
			priv->extended = true;
			return 0;
		}
		if (scan_code & 0x80) {
			scan_code &= 0x7f;
			release = true;
		}
		if (priv->extended) {
			priv->extended = false;
			for (i = 0; ext_key_map[i]; i++) {
				if (ext_key_map[i] == scan_code) {
					scan_code = 0x60 + i;
					break;
				}
			}
			/* not found ? */
			if (!ext_key_map[i])
				return 0;
		}

		input_add_keycode(input, scan_code, release);
		return 1;
	}
}

/* i8042_kbd_init - reset keyboard and init state flags */
static int i8042_start(struct udevice *dev)
{
	struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev);
	struct i8042_kbd_priv *priv = dev_get_priv(dev);
	struct input_config *input = &uc_priv->input;
	int keymap, try;
	char *penv;
	int ret;

	if (!kbd_controller_present() || board_i8042_skip()) {
		debug("i8042 keyboard controller is not present\n");
		return -ENOENT;
	}

	/* Init keyboard device (default US layout) */
	keymap = KBD_US;
	penv = getenv("keymap");
	if (penv != NULL) {
		if (strncmp(penv, "de", 3) == 0)
			keymap = KBD_GER;
	}

	for (try = 0; kbd_reset(priv->quirks) != 0; try++) {
		if (try >= KBD_RESET_TRIES)
			return -1;
	}

	ret = input_add_tables(input, keymap == KBD_GER);
	if (ret)
		return ret;

	i8042_kbd_update_leds(dev, NORMAL);
	debug("%s: started\n", __func__);

	return 0;
}

/**
 * Set up the i8042 keyboard. This is called by the stdio device handler
 *
 * We want to do this init when the keyboard is actually used rather than
 * at start-up, since keyboard input may not currently be selected.
 *
 * Once the keyboard starts there will be a period during which we must
 * wait for the keyboard to init. We do this only when a key is first
 * read - see kbd_wait_for_fifo_init().
 *
 * @return 0 if ok, -ve on error
 */
static int i8042_kbd_probe(struct udevice *dev)
{
	struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev);
	struct i8042_kbd_priv *priv = dev_get_priv(dev);
	struct stdio_dev *sdev = &uc_priv->sdev;
	struct input_config *input = &uc_priv->input;
	int ret;

	if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
			    "intel,duplicate-por"))
		priv->quirks |= QUIRK_DUP_POR;

	/* Register the device. i8042_start() will be called soon */
	input->dev = dev;
	input->read_keys = i8042_kbd_check;
	input_allow_repeats(input, true);
	strcpy(sdev->name, "i8042-kbd");
	ret = input_stdio_register(sdev);
	if (ret) {
		debug("%s: input_stdio_register() failed\n", __func__);
		return ret;
	}
	debug("%s: ready\n", __func__);

	return 0;
}

static const struct keyboard_ops i8042_kbd_ops = {
	.start	= i8042_start,
	.update_leds	= i8042_kbd_update_leds,
};

static const struct udevice_id i8042_kbd_ids[] = {
	{ .compatible = "intel,i8042-keyboard" },
	{ }
};

U_BOOT_DRIVER(i8042_kbd) = {
	.name	= "i8042_kbd",
	.id	= UCLASS_KEYBOARD,
	.of_match = i8042_kbd_ids,
	.probe = i8042_kbd_probe,
	.ops	= &i8042_kbd_ops,
	.priv_auto_alloc_size = sizeof(struct i8042_kbd_priv),
};
