// 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 <dm.h>
#include <hexdump.h>
#include <video_osd.h>
#include <malloc.h>

static int do_osd_write(cmd_tbl_t *cmdtp, int flag, int argc,
			char * const argv[])
{
	struct udevice *dev;
	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;

	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;
	}

	for (uclass_first_device(UCLASS_VIDEO_OSD, &dev);
	     dev;
	     uclass_next_device(&dev)) {
		int res;

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

	free(buffer);

	return CMD_RET_SUCCESS;
}

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

	if (argc < 5)
		return CMD_RET_USAGE;

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

	for (uclass_first_device(UCLASS_VIDEO_OSD, &dev);
	     dev;
	     uclass_next_device(&dev)) {
		int res;

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

	return CMD_RET_SUCCESS;
}

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

	if (argc < 3)
		return CMD_RET_USAGE;

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

	for (uclass_first_device(UCLASS_VIDEO_OSD, &dev);
	     dev;
	     uclass_next_device(&dev)) {
		int res;

		res = video_osd_set_size(dev, x, y);

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

	return CMD_RET_SUCCESS;
}

U_BOOT_CMD(
	osdw, 5, 0, do_osd_write,
	"write 16-bit hex encoded buffer to osd memory",
	"osdw [pos_x] [pos_y] [buffer] [count] - write 8-bit hex encoded buffer to osd memory\n"
);

U_BOOT_CMD(
	osdp, 5, 0, do_osd_print,
	"write ASCII buffer to osd memory",
	"osdp [pos_x] [pos_y] [color] [text] - write ASCII buffer to osd memory\n"
);

U_BOOT_CMD(
	osdsize, 3, 0, do_osd_size,
	"set OSD XY size in characters",
	"osdsize [size_x] [size_y] - set OSD XY size in characters\n"
);
