// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2011 The Chromium OS Authors.
 */

/*
 * This provide a test serial port. It provides an emulated serial port where
 * a test program and read out the serial output and inject serial input for
 * U-Boot.
 */

#include <common.h>
#include <console.h>
#include <dm.h>
#include <lcd.h>
#include <os.h>
#include <serial.h>
#include <video.h>
#include <asm/global_data.h>
#include <linux/compiler.h>
#include <asm/serial.h>
#include <asm/state.h>

DECLARE_GLOBAL_DATA_PTR;

static size_t _sandbox_serial_written = 1;
static bool sandbox_serial_enabled = true;

size_t sandbox_serial_written(void)
{
	return _sandbox_serial_written;
}

void sandbox_serial_endisable(bool enabled)
{
	sandbox_serial_enabled = enabled;
}

/**
 * output_ansi_colour() - Output an ANSI colour code
 *
 * @colour: Colour to output (0-7)
 */
static void output_ansi_colour(int colour)
{
	char ansi_code[] = "\x1b[1;3Xm";

	ansi_code[5] = '0' + colour;
	os_write(1, ansi_code, sizeof(ansi_code) - 1);
}

static void output_ansi_reset(void)
{
	os_write(1, "\x1b[0m", 4);
}

static int sandbox_serial_probe(struct udevice *dev)
{
	struct sandbox_state *state = state_get_current();
	struct sandbox_serial_priv *priv = dev_get_priv(dev);

	if (state->term_raw != STATE_TERM_COOKED)
		os_tty_raw(0, state->term_raw == STATE_TERM_RAW_WITH_SIGS);
	priv->start_of_line = 0;

	if (state->term_raw != STATE_TERM_RAW)
		disable_ctrlc(1);
	membuff_init(&priv->buf, priv->serial_buf, sizeof(priv->serial_buf));

	return 0;
}

static int sandbox_serial_remove(struct udevice *dev)
{
	struct sandbox_serial_plat *plat = dev_get_plat(dev);

	if (plat->colour != -1)
		output_ansi_reset();

	return 0;
}

static void sandbox_print_color(struct udevice *dev)
{
	struct sandbox_serial_priv *priv = dev_get_priv(dev);
	struct sandbox_serial_plat *plat = dev_get_plat(dev);

	/* With of-platdata we don't real the colour correctly, so disable it */
	if (!CONFIG_IS_ENABLED(OF_PLATDATA) && priv->start_of_line &&
	    plat->colour != -1) {
		priv->start_of_line = false;
		output_ansi_colour(plat->colour);
	}
}

static int sandbox_serial_putc(struct udevice *dev, const char ch)
{
	struct sandbox_serial_priv *priv = dev_get_priv(dev);

	if (ch == '\n')
		priv->start_of_line = true;

	if (sandbox_serial_enabled) {
		sandbox_print_color(dev);
		os_write(1, &ch, 1);
	}
	_sandbox_serial_written += 1;
	return 0;
}

static ssize_t sandbox_serial_puts(struct udevice *dev, const char *s,
				   size_t len)
{
	struct sandbox_serial_priv *priv = dev_get_priv(dev);
	ssize_t ret;

	if (s[len - 1] == '\n')
		priv->start_of_line = true;

	if (sandbox_serial_enabled) {
		sandbox_print_color(dev);
		ret = os_write(1, s, len);
		if (ret < 0)
			return ret;
	} else {
		ret = len;
	}
	_sandbox_serial_written += ret;
	return ret;
}

static int sandbox_serial_pending(struct udevice *dev, bool input)
{
	struct sandbox_serial_priv *priv = dev_get_priv(dev);
	ssize_t count;
	char *data;
	int avail;

	if (!input)
		return 0;

	os_usleep(100);
	if (IS_ENABLED(CONFIG_DM_VIDEO) && !IS_ENABLED(CONFIG_SPL_BUILD))
		video_sync_all();
	avail = membuff_putraw(&priv->buf, 100, false, &data);
	if (!avail)
		return 1;	/* buffer full */

	count = os_read(0, data, avail);
	if (count > 0)
		membuff_putraw(&priv->buf, count, true, &data);

	return membuff_avail(&priv->buf);
}

static int sandbox_serial_getc(struct udevice *dev)
{
	struct sandbox_serial_priv *priv = dev_get_priv(dev);

	if (!sandbox_serial_pending(dev, true))
		return -EAGAIN;	/* buffer empty */

	return membuff_getbyte(&priv->buf);
}

#ifdef CONFIG_DEBUG_UART_SANDBOX

#include <debug_uart.h>

static inline void _debug_uart_init(void)
{
}

static inline void _debug_uart_putc(int ch)
{
	os_putc(ch);
}

DEBUG_UART_FUNCS

#endif /* CONFIG_DEBUG_UART_SANDBOX */

static int sandbox_serial_getconfig(struct udevice *dev, uint *serial_config)
{
	uint config = SERIAL_DEFAULT_CONFIG;

	if (!serial_config)
		return -EINVAL;

	*serial_config = config;

	return 0;
}

static int sandbox_serial_setconfig(struct udevice *dev, uint serial_config)
{
	u8 parity = SERIAL_GET_PARITY(serial_config);
	u8 bits = SERIAL_GET_BITS(serial_config);
	u8 stop = SERIAL_GET_STOP(serial_config);

	if (bits != SERIAL_8_BITS || stop != SERIAL_ONE_STOP ||
	    parity != SERIAL_PAR_NONE)
		return -ENOTSUPP; /* not supported in driver*/

	return 0;
}

static int sandbox_serial_getinfo(struct udevice *dev,
				  struct serial_device_info *serial_info)
{
	struct serial_device_info info = {
		.type = SERIAL_CHIP_UNKNOWN,
		.addr_space = SERIAL_ADDRESS_SPACE_IO,
		.addr = SERIAL_DEFAULT_ADDRESS,
		.reg_width = 1,
		.reg_offset = 0,
		.reg_shift = 0,
		.clock = SERIAL_DEFAULT_CLOCK,
	};

	if (!serial_info)
		return -EINVAL;

	*serial_info = info;

	return 0;
}

static const char * const ansi_colour[] = {
	"black", "red", "green", "yellow", "blue", "megenta", "cyan",
	"white",
};

static int sandbox_serial_of_to_plat(struct udevice *dev)
{
	struct sandbox_serial_plat *plat = dev_get_plat(dev);
	const char *colour;
	int i;

	if (CONFIG_IS_ENABLED(OF_PLATDATA))
		return 0;
	plat->colour = -1;
	colour = dev_read_string(dev, "sandbox,text-colour");
	if (colour) {
		for (i = 0; i < ARRAY_SIZE(ansi_colour); i++) {
			if (!strcmp(colour, ansi_colour[i])) {
				plat->colour = i;
				break;
			}
		}
	}

	return 0;
}

static const struct dm_serial_ops sandbox_serial_ops = {
	.putc = sandbox_serial_putc,
	.puts = sandbox_serial_puts,
	.pending = sandbox_serial_pending,
	.getc = sandbox_serial_getc,
	.getconfig = sandbox_serial_getconfig,
	.setconfig = sandbox_serial_setconfig,
	.getinfo = sandbox_serial_getinfo,
};

static const struct udevice_id sandbox_serial_ids[] = {
	{ .compatible = "sandbox,serial" },
	{ }
};

U_BOOT_DRIVER(sandbox_serial) = {
	.name	= "sandbox_serial",
	.id	= UCLASS_SERIAL,
	.of_match = sandbox_serial_ids,
	.of_to_plat = sandbox_serial_of_to_plat,
	.plat_auto	= sizeof(struct sandbox_serial_plat),
	.priv_auto	= sizeof(struct sandbox_serial_priv),
	.probe = sandbox_serial_probe,
	.remove = sandbox_serial_remove,
	.ops	= &sandbox_serial_ops,
	.flags = DM_FLAG_PRE_RELOC,
};

#if CONFIG_IS_ENABLED(OF_REAL)
static const struct sandbox_serial_plat platdata_non_fdt = {
	.colour = -1,
};

U_BOOT_DRVINFO(serial_sandbox_non_fdt) = {
	.name = "sandbox_serial",
	.plat = &platdata_non_fdt,
};
#endif
