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

/*
 * 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 <dm.h>
#include <fdtdec.h>
#include <lcd.h>
#include <os.h>
#include <serial.h>
#include <linux/compiler.h>
#include <asm/state.h>

DECLARE_GLOBAL_DATA_PTR;

/*
 *
 *   serial_buf: A buffer that holds keyboard characters for the
 *		 Sandbox U-boot.
 *
 * invariants:
 *   serial_buf_write		 == serial_buf_read -> empty buffer
 *   (serial_buf_write + 1) % 16 == serial_buf_read -> full buffer
 */
static char serial_buf[16];
static unsigned int serial_buf_write;
static unsigned int serial_buf_read;

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

struct sandbox_serial_priv {
	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;

	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;

	if (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 unsigned int increment_buffer_index(unsigned int index)
{
	return (index + 1) % ARRAY_SIZE(serial_buf);
}

static int sandbox_serial_pending(struct udevice *dev, bool input)
{
	const unsigned int next_index =
		increment_buffer_index(serial_buf_write);
	ssize_t count;

	if (!input)
		return 0;

	os_usleep(100);
#ifdef CONFIG_LCD
	lcd_sync();
#endif
	if (next_index == serial_buf_read)
		return 1;	/* buffer full */

	count = os_read_no_block(0, &serial_buf[serial_buf_write], 1);
	if (count == 1)
		serial_buf_write = next_index;

	return serial_buf_write != serial_buf_read;
}

static int sandbox_serial_getc(struct udevice *dev)
{
	int result;

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

	result = serial_buf[serial_buf_read];
	serial_buf_read = increment_buffer_index(serial_buf_read);
	return result;
}

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;

	plat->colour = -1;
	colour = fdt_getprop(gd->fdt_blob, dev->of_offset,
			     "sandbox,text-colour", NULL);
	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,
};

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

U_BOOT_DRIVER(serial_sandbox) = {
	.name	= "serial_sandbox",
	.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,
};

static const struct sandbox_serial_platdata platdata_non_fdt = {
	.colour = -1,
};

U_BOOT_DEVICE(serial_sandbox_non_fdt) = {
	.name = "serial_sandbox",
	.platdata = &platdata_non_fdt,
};
