/*
 * (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;

	/* 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,
			    "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),
};
