// 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 <linux/compiler.h>
#include <asm/state.h>

DECLARE_GLOBAL_DATA_PTR;

struct sandbox_serial_platdata {
	int colour;	/* Text colour to use for output, -1 for none */
};

/**
 * struct sandbox_serial_priv - Private data for this driver
 *
 * @buf: holds input characters available to be read by this driver
 */
struct sandbox_serial_priv {
	struct membuff buf;
	char serial_buf[16];
	bool start_of_line;
};

/**
 * 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_platdata *plat = dev->platdata;

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

	return 0;
}

static int sandbox_serial_putc(struct udevice *dev, const char ch)
{
	struct sandbox_serial_priv *priv = dev_get_priv(dev);
	struct sandbox_serial_platdata *plat = dev->platdata;

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

	os_write(1, &ch, 1);
	if (ch == '\n')
		priv->start_of_line = true;

	return 0;
}

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_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_ofdata_to_platdata(struct udevice *dev)
{
	struct sandbox_serial_platdata *plat = dev->platdata;
	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,
	.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,
	.ofdata_to_platdata = sandbox_serial_ofdata_to_platdata,
	.platdata_auto_alloc_size = sizeof(struct sandbox_serial_platdata),
	.priv_auto_alloc_size = 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_PLATDATA)
static const struct sandbox_serial_platdata platdata_non_fdt = {
	.colour = -1,
};

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