// 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 <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 = hextoul(argv[1], NULL);
	y = hextoul(argv[2], NULL);
	hexstr = argv[3];
	count = (argc > 4) ? hextoul(argv[4], NULL) : 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 = hextoul(argv[1], NULL);
	y = hextoul(argv[2], NULL);
	color = hextoul(argv[3], NULL);
	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 = hextoul(argv[1], NULL);
	y = hextoul(argv[2], NULL);

	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 = dectoul(argv[1], NULL);

		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 = dectoul(argv[1], NULL);
		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;
}

U_BOOT_LONGHELP(osd,
	"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
);
