video_osd: Add osd sandbox driver and tests
Add sandbox driver and tests for the new OSD uclass.
Signed-off-by: Mario Six <mario.six@gdsys.cc>
Reviewed-by: Simon Glass <sjg@chromium.org>
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 1e2cbe7..c680666 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -692,6 +692,12 @@
is a (usually text-oriented) graphics buffer to show information on
a display.
+config SANDBOX_OSD
+ bool "Enable sandbox OSD"
+ depends on OSD
+ help
+ Enable support for sandbox OSD device used for testing purposes.
+
config IHS_VIDEO_OUT
bool "Enable IHS video out driver"
depends on OSD
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 290747b..b31017e 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -34,6 +34,7 @@
obj-$(CONFIG_LOGICORE_DP_TX) += logicore_dp_tx.o
obj-$(CONFIG_OSD) += video_osd-uclass.o
obj-$(CONFIG_PXA_LCD) += pxa_lcd.o
+obj-$(CONFIG_SANDBOX_OSD) += sandbox_osd.o
obj-$(CONFIG_S6E8AX0) += s6e8ax0.o
obj-$(CONFIG_SCF0403_LCD) += scf0403_lcd.o
obj-$(CONFIG_VIDEO_BCM2835) += bcm2835.o
diff --git a/drivers/video/sandbox_osd.c b/drivers/video/sandbox_osd.c
new file mode 100644
index 0000000..dd84489
--- /dev/null
+++ b/drivers/video/sandbox_osd.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
+ */
+#include <common.h>
+#include <display.h>
+#include <dm.h>
+#include <video_osd.h>
+
+#include "sandbox_osd.h"
+
+struct sandbox_osd_priv {
+ uint width;
+ uint height;
+ u16 *buf;
+};
+
+static const struct udevice_id sandbox_osd_ids[] = {
+ { .compatible = "sandbox,sandbox_osd" },
+ { }
+};
+
+inline u16 make_memval(u8 chr, u8 color)
+{
+ return chr * 0x100 + color;
+}
+
+int sandbox_osd_get_info(struct udevice *dev, struct video_osd_info *info)
+{
+ struct sandbox_osd_priv *priv = dev_get_priv(dev);
+
+ info->width = priv->width;
+ info->height = priv->height;
+ info->major_version = 1;
+ info->minor_version = 0;
+
+ return 0;
+}
+
+int sandbox_osd_set_mem(struct udevice *dev, uint col, uint row, u8 *buf,
+ size_t buflen, uint count)
+{
+ struct sandbox_osd_priv *priv = dev_get_priv(dev);
+ int pos;
+ u8 *mem = (u8 *)priv->buf;
+ int i;
+
+ pos = 2 * (row * priv->width + col);
+
+ if (pos >= 2 * (priv->width * priv->height))
+ return -EINVAL;
+
+ for (i = 0; i < count; i++)
+ memcpy(mem + pos + (i * buflen), buf, buflen);
+
+ return 0;
+}
+
+int _sandbox_osd_set_size(struct udevice *dev, uint col, uint row)
+{
+ struct sandbox_osd_priv *priv = dev_get_priv(dev);
+ int i;
+ uint size;
+
+ priv->width = col;
+ priv->height = row;
+ size = priv->width * priv->height;
+ if (!priv->buf)
+ priv->buf = calloc(size, sizeof(u16));
+ else
+ priv->buf = realloc(priv->buf, size * sizeof(u16));
+
+ if (!priv->buf)
+ return -ENOMEM;
+
+ /* Fill OSD with black spaces */
+ for (i = 0; i < size; i++)
+ priv->buf[i] = make_memval(' ', 'k');
+
+ return 0;
+}
+
+int sandbox_osd_set_size(struct udevice *dev, uint col, uint row)
+{
+ return _sandbox_osd_set_size(dev, col, row);
+}
+
+int sandbox_osd_print(struct udevice *dev, uint col, uint row, ulong color,
+ char *text)
+{
+ struct sandbox_osd_priv *priv = dev_get_priv(dev);
+ char cval;
+ char *p;
+ int pos;
+
+ if (col >= priv->width || row >= priv->height)
+ return -EINVAL;
+
+ switch (color) {
+ case COLOR_BLACK:
+ cval = 'k';
+ break;
+ case COLOR_WHITE:
+ cval = 'w';
+ break;
+ case COLOR_RED:
+ cval = 'r';
+ break;
+ case COLOR_GREEN:
+ cval = 'g';
+ break;
+ case COLOR_BLUE:
+ cval = 'b';
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ p = text;
+ pos = row * priv->width + col;
+
+ while (*p)
+ priv->buf[pos++] = make_memval(*(p++), cval);
+
+ return 0;
+}
+
+int sandbox_osd_get_mem(struct udevice *dev, u8 *buf, size_t buflen)
+{
+ struct sandbox_osd_priv *priv = dev_get_priv(dev);
+ uint memsize = 2 * (priv->width * priv->height);
+
+ if (buflen < memsize)
+ return -EINVAL;
+
+ memcpy(buf, priv->buf, memsize);
+
+ return 0;
+}
+
+static const struct video_osd_ops sandbox_osd_ops = {
+ .get_info = sandbox_osd_get_info,
+ .set_mem = sandbox_osd_set_mem,
+ .set_size = sandbox_osd_set_size,
+ .print = sandbox_osd_print,
+};
+
+int sandbox_osd_probe(struct udevice *dev)
+{
+ return _sandbox_osd_set_size(dev, 10, 10);
+}
+
+U_BOOT_DRIVER(sandbox_osd_drv) = {
+ .name = "sandbox_osd_drv",
+ .id = UCLASS_VIDEO_OSD,
+ .ops = &sandbox_osd_ops,
+ .of_match = sandbox_osd_ids,
+ .probe = sandbox_osd_probe,
+ .priv_auto_alloc_size = sizeof(struct sandbox_osd_priv),
+};
diff --git a/drivers/video/sandbox_osd.h b/drivers/video/sandbox_osd.h
new file mode 100644
index 0000000..15a2c91
--- /dev/null
+++ b/drivers/video/sandbox_osd.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
+ */
+
+enum {
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_RED,
+ COLOR_GREEN,
+ COLOR_BLUE,
+};