// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2017
 * Mario Six,  Guntermann & Drunck GmbH, mario.six@gdsys.cc
 *
 * based on the gdsys osd driver, which is
 *
 * (C) Copyright 2010
 * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
 */

#include <common.h>
#include <command.h>
#include <dm.h>
#include <hexdump.h>
#include <video_osd.h>
#include <malloc.h>

/* Container for selected OSD device */
static struct udevice *osd_cur;

/**
 * cmd_osd_set_osd_num() - Set the OSD selected for operation
 *
 * Set the OSD device, which will be used by all subsequent OSD commands.
 *
 * Devices are identified by their uclass sequence number (as listed by 'osd
 * show').
 *
 * @osdnum: The OSD device to be selected, identified by its sequence number.
 * Return: 0 if OK, -ve on error
 */
static int cmd_osd_set_osd_num(unsigned int osdnum)
{
	struct udevice *osd;
	int res;

	res = uclass_get_device_by_seq(UCLASS_VIDEO_OSD, osdnum, &osd);
	if (res) {
		printf("%s: No OSD %u (err = %d)\n", __func__, osdnum, res);
		return res;
	}
	osd_cur = osd;

	return 0;
}

/**
 * osd_get_osd_cur() - Get the selected OSD device
 *
 * Get the OSD device that is used by all OSD commands.
 *
 * @osdp: Pointer to structure that will receive the currently selected OSD
 *	  device.
 * Return: 0 if OK, -ve on error
 */
static int osd_get_osd_cur(struct udevice **osdp)
{
	if (!osd_cur) {
		puts("No osd selected\n");
		return -ENODEV;
	}
	*osdp = osd_cur;

	return 0;
}

/**
 * show_osd() - Display information about a OSD device
 *
 * Display a device's ID (sequence number), and whether it is active (i.e.
 * probed) or not.
 *
 * @osd: OSD device to print information for
 */
static void show_osd(struct udevice *osd)
{
	printf("OSD %d:\t%s", dev_seq(osd), osd->name);
	if (device_active(osd))
		printf("  (active)");
	printf("\n");
}

static int do_osd_write(struct cmd_tbl *cmdtp, int flag, int argc,
			char *const argv[])
{
	uint x, y;
	uint count;
	char *hexstr;
	u8 *buffer;
	size_t buflen;
	int res;

	if (argc < 4 || (strlen(argv[3]) % 2))
		return CMD_RET_USAGE;

	if (!osd_cur) {
		puts("No osd selected\n");
		return CMD_RET_FAILURE;
	}

	x = simple_strtoul(argv[1], NULL, 16);
	y = simple_strtoul(argv[2], NULL, 16);
	hexstr = argv[3];
	count = (argc > 4) ? simple_strtoul(argv[4], NULL, 16) : 1;

	buflen = strlen(hexstr) / 2;

	buffer = malloc(buflen);
	if (!buffer) {
		puts("Memory allocation failure\n");
		return CMD_RET_FAILURE;
	}

	res = hex2bin(buffer, hexstr, buflen);
	if (res) {
		free(buffer);
		puts("Hexadecimal input contained invalid characters\n");
		return CMD_RET_FAILURE;
	}

	res = video_osd_set_mem(osd_cur, x, y, buffer, buflen, count);
	if (res) {
		free(buffer);
		printf("%s: Could not write to video mem\n",
		       osd_cur->name);
		return CMD_RET_FAILURE;
	}

	free(buffer);

	return CMD_RET_SUCCESS;
}

static int do_osd_print(struct cmd_tbl *cmdtp, int flag, int argc,
			char *const argv[])
{
	uint x, y;
	u8 color;
	char *text;
	int res;

	if (argc < 5)
		return CMD_RET_USAGE;

	if (!osd_cur) {
		puts("No osd selected\n");
		return CMD_RET_FAILURE;
	}

	x = simple_strtoul(argv[1], NULL, 16);
	y = simple_strtoul(argv[2], NULL, 16);
	color = simple_strtoul(argv[3], NULL, 16);
	text = argv[4];

	res = video_osd_print(osd_cur, x, y, color, text);
	if (res) {
		printf("Could not print string to osd %s\n", osd_cur->name);
		return CMD_RET_FAILURE;
	}

	return CMD_RET_SUCCESS;
}

static int do_osd_size(struct cmd_tbl *cmdtp, int flag, int argc,
		       char *const argv[])
{
	uint x, y;
	int res;

	if (argc < 3)
		return CMD_RET_USAGE;

	if (!osd_cur) {
		puts("No osd selected\n");
		return CMD_RET_FAILURE;
	}

	x = simple_strtoul(argv[1], NULL, 16);
	y = simple_strtoul(argv[2], NULL, 16);

	res = video_osd_set_size(osd_cur, x, y);
	if (res) {
		printf("Could not set size on osd %s\n", osd_cur->name);
		return CMD_RET_FAILURE;
	}

	return CMD_RET_SUCCESS;
}

static int do_show_osd(struct cmd_tbl *cmdtp, int flag, int argc,
		       char *const argv[])
{
	struct udevice *osd;

	if (argc == 1) {
		/* show all OSDs */
		struct uclass *uc;
		int res;

		res = uclass_get(UCLASS_VIDEO_OSD, &uc);
		if (res) {
			printf("Error while getting OSD uclass (err=%d)\n",
			       res);
			return CMD_RET_FAILURE;
		}

		uclass_foreach_dev(osd, uc)
			show_osd(osd);
	} else {
		int i, res;

		/* show specific OSD */
		i = simple_strtoul(argv[1], NULL, 10);

		res = uclass_get_device_by_seq(UCLASS_VIDEO_OSD, i, &osd);
		if (res) {
			printf("Invalid osd %d: err=%d\n", i, res);
			return CMD_RET_FAILURE;
		}
		show_osd(osd);
	}

	return CMD_RET_SUCCESS;
}

static int do_osd_num(struct cmd_tbl *cmdtp, int flag, int argc,
		      char *const argv[])
{
	int osd_no;
	int res = 0;

	if (argc == 1) {
		/* querying current setting */
		struct udevice *osd;

		if (!osd_get_osd_cur(&osd))
			osd_no = dev_seq(osd);
		else
			osd_no = -1;
		printf("Current osd is %d\n", osd_no);
	} else {
		osd_no = simple_strtoul(argv[1], NULL, 10);
		printf("Setting osd to %d\n", osd_no);

		res = cmd_osd_set_osd_num(osd_no);
		if (res)
			printf("Failure changing osd number (err = %d)\n", res);
	}

	return res ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
}

static struct cmd_tbl cmd_osd_sub[] = {
	U_BOOT_CMD_MKENT(show, 1, 1, do_show_osd, "", ""),
	U_BOOT_CMD_MKENT(dev, 1, 1, do_osd_num, "", ""),
	U_BOOT_CMD_MKENT(write, 4, 1, do_osd_write, "", ""),
	U_BOOT_CMD_MKENT(print, 4, 1, do_osd_print, "", ""),
	U_BOOT_CMD_MKENT(size, 2, 1, do_osd_size, "", ""),
};

static int do_osd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	struct cmd_tbl *c;

	if (argc < 2)
		return CMD_RET_USAGE;

	/* Strip off leading 'osd' command argument */
	argc--;
	argv++;

	c = find_cmd_tbl(argv[0], &cmd_osd_sub[0], ARRAY_SIZE(cmd_osd_sub));

	if (c)
		return c->cmd(cmdtp, flag, argc, argv);
	else
		return CMD_RET_USAGE;
}

static char osd_help_text[] =
	"show  - show OSD info\n"
	"osd dev [dev] - show or set current OSD\n"
	"write [pos_x] [pos_y] [buffer] [count] - write 8-bit hex encoded buffer to osd memory at a given position\n"
	"print [pos_x] [pos_y] [color] [text] - write ASCII buffer (given by text data and driver-specific color information) to osd memory\n"
	"size [size_x] [size_y] - set OSD XY size in characters\n";

U_BOOT_CMD(
	osd, 6, 1, do_osd,
	"OSD sub-system",
	osd_help_text
);
