1*4eea5318SMario Six // SPDX-License-Identifier: GPL-2.0+
2*4eea5318SMario Six /*
3*4eea5318SMario Six * (C) Copyright 2018
4*4eea5318SMario Six * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
5*4eea5318SMario Six */
6*4eea5318SMario Six #include <common.h>
7*4eea5318SMario Six #include <display.h>
8*4eea5318SMario Six #include <dm.h>
9*4eea5318SMario Six #include <video_osd.h>
10*4eea5318SMario Six
11*4eea5318SMario Six #include "sandbox_osd.h"
12*4eea5318SMario Six
13*4eea5318SMario Six struct sandbox_osd_priv {
14*4eea5318SMario Six uint width;
15*4eea5318SMario Six uint height;
16*4eea5318SMario Six u16 *buf;
17*4eea5318SMario Six };
18*4eea5318SMario Six
19*4eea5318SMario Six static const struct udevice_id sandbox_osd_ids[] = {
20*4eea5318SMario Six { .compatible = "sandbox,sandbox_osd" },
21*4eea5318SMario Six { }
22*4eea5318SMario Six };
23*4eea5318SMario Six
make_memval(u8 chr,u8 color)24*4eea5318SMario Six inline u16 make_memval(u8 chr, u8 color)
25*4eea5318SMario Six {
26*4eea5318SMario Six return chr * 0x100 + color;
27*4eea5318SMario Six }
28*4eea5318SMario Six
sandbox_osd_get_info(struct udevice * dev,struct video_osd_info * info)29*4eea5318SMario Six int sandbox_osd_get_info(struct udevice *dev, struct video_osd_info *info)
30*4eea5318SMario Six {
31*4eea5318SMario Six struct sandbox_osd_priv *priv = dev_get_priv(dev);
32*4eea5318SMario Six
33*4eea5318SMario Six info->width = priv->width;
34*4eea5318SMario Six info->height = priv->height;
35*4eea5318SMario Six info->major_version = 1;
36*4eea5318SMario Six info->minor_version = 0;
37*4eea5318SMario Six
38*4eea5318SMario Six return 0;
39*4eea5318SMario Six }
40*4eea5318SMario Six
sandbox_osd_set_mem(struct udevice * dev,uint col,uint row,u8 * buf,size_t buflen,uint count)41*4eea5318SMario Six int sandbox_osd_set_mem(struct udevice *dev, uint col, uint row, u8 *buf,
42*4eea5318SMario Six size_t buflen, uint count)
43*4eea5318SMario Six {
44*4eea5318SMario Six struct sandbox_osd_priv *priv = dev_get_priv(dev);
45*4eea5318SMario Six int pos;
46*4eea5318SMario Six u8 *mem = (u8 *)priv->buf;
47*4eea5318SMario Six int i;
48*4eea5318SMario Six
49*4eea5318SMario Six pos = 2 * (row * priv->width + col);
50*4eea5318SMario Six
51*4eea5318SMario Six if (pos >= 2 * (priv->width * priv->height))
52*4eea5318SMario Six return -EINVAL;
53*4eea5318SMario Six
54*4eea5318SMario Six for (i = 0; i < count; i++)
55*4eea5318SMario Six memcpy(mem + pos + (i * buflen), buf, buflen);
56*4eea5318SMario Six
57*4eea5318SMario Six return 0;
58*4eea5318SMario Six }
59*4eea5318SMario Six
_sandbox_osd_set_size(struct udevice * dev,uint col,uint row)60*4eea5318SMario Six int _sandbox_osd_set_size(struct udevice *dev, uint col, uint row)
61*4eea5318SMario Six {
62*4eea5318SMario Six struct sandbox_osd_priv *priv = dev_get_priv(dev);
63*4eea5318SMario Six int i;
64*4eea5318SMario Six uint size;
65*4eea5318SMario Six
66*4eea5318SMario Six priv->width = col;
67*4eea5318SMario Six priv->height = row;
68*4eea5318SMario Six size = priv->width * priv->height;
69*4eea5318SMario Six if (!priv->buf)
70*4eea5318SMario Six priv->buf = calloc(size, sizeof(u16));
71*4eea5318SMario Six else
72*4eea5318SMario Six priv->buf = realloc(priv->buf, size * sizeof(u16));
73*4eea5318SMario Six
74*4eea5318SMario Six if (!priv->buf)
75*4eea5318SMario Six return -ENOMEM;
76*4eea5318SMario Six
77*4eea5318SMario Six /* Fill OSD with black spaces */
78*4eea5318SMario Six for (i = 0; i < size; i++)
79*4eea5318SMario Six priv->buf[i] = make_memval(' ', 'k');
80*4eea5318SMario Six
81*4eea5318SMario Six return 0;
82*4eea5318SMario Six }
83*4eea5318SMario Six
sandbox_osd_set_size(struct udevice * dev,uint col,uint row)84*4eea5318SMario Six int sandbox_osd_set_size(struct udevice *dev, uint col, uint row)
85*4eea5318SMario Six {
86*4eea5318SMario Six return _sandbox_osd_set_size(dev, col, row);
87*4eea5318SMario Six }
88*4eea5318SMario Six
sandbox_osd_print(struct udevice * dev,uint col,uint row,ulong color,char * text)89*4eea5318SMario Six int sandbox_osd_print(struct udevice *dev, uint col, uint row, ulong color,
90*4eea5318SMario Six char *text)
91*4eea5318SMario Six {
92*4eea5318SMario Six struct sandbox_osd_priv *priv = dev_get_priv(dev);
93*4eea5318SMario Six char cval;
94*4eea5318SMario Six char *p;
95*4eea5318SMario Six int pos;
96*4eea5318SMario Six
97*4eea5318SMario Six if (col >= priv->width || row >= priv->height)
98*4eea5318SMario Six return -EINVAL;
99*4eea5318SMario Six
100*4eea5318SMario Six switch (color) {
101*4eea5318SMario Six case COLOR_BLACK:
102*4eea5318SMario Six cval = 'k';
103*4eea5318SMario Six break;
104*4eea5318SMario Six case COLOR_WHITE:
105*4eea5318SMario Six cval = 'w';
106*4eea5318SMario Six break;
107*4eea5318SMario Six case COLOR_RED:
108*4eea5318SMario Six cval = 'r';
109*4eea5318SMario Six break;
110*4eea5318SMario Six case COLOR_GREEN:
111*4eea5318SMario Six cval = 'g';
112*4eea5318SMario Six break;
113*4eea5318SMario Six case COLOR_BLUE:
114*4eea5318SMario Six cval = 'b';
115*4eea5318SMario Six break;
116*4eea5318SMario Six default:
117*4eea5318SMario Six return -EINVAL;
118*4eea5318SMario Six }
119*4eea5318SMario Six
120*4eea5318SMario Six p = text;
121*4eea5318SMario Six pos = row * priv->width + col;
122*4eea5318SMario Six
123*4eea5318SMario Six while (*p)
124*4eea5318SMario Six priv->buf[pos++] = make_memval(*(p++), cval);
125*4eea5318SMario Six
126*4eea5318SMario Six return 0;
127*4eea5318SMario Six }
128*4eea5318SMario Six
sandbox_osd_get_mem(struct udevice * dev,u8 * buf,size_t buflen)129*4eea5318SMario Six int sandbox_osd_get_mem(struct udevice *dev, u8 *buf, size_t buflen)
130*4eea5318SMario Six {
131*4eea5318SMario Six struct sandbox_osd_priv *priv = dev_get_priv(dev);
132*4eea5318SMario Six uint memsize = 2 * (priv->width * priv->height);
133*4eea5318SMario Six
134*4eea5318SMario Six if (buflen < memsize)
135*4eea5318SMario Six return -EINVAL;
136*4eea5318SMario Six
137*4eea5318SMario Six memcpy(buf, priv->buf, memsize);
138*4eea5318SMario Six
139*4eea5318SMario Six return 0;
140*4eea5318SMario Six }
141*4eea5318SMario Six
142*4eea5318SMario Six static const struct video_osd_ops sandbox_osd_ops = {
143*4eea5318SMario Six .get_info = sandbox_osd_get_info,
144*4eea5318SMario Six .set_mem = sandbox_osd_set_mem,
145*4eea5318SMario Six .set_size = sandbox_osd_set_size,
146*4eea5318SMario Six .print = sandbox_osd_print,
147*4eea5318SMario Six };
148*4eea5318SMario Six
sandbox_osd_probe(struct udevice * dev)149*4eea5318SMario Six int sandbox_osd_probe(struct udevice *dev)
150*4eea5318SMario Six {
151*4eea5318SMario Six return _sandbox_osd_set_size(dev, 10, 10);
152*4eea5318SMario Six }
153*4eea5318SMario Six
154*4eea5318SMario Six U_BOOT_DRIVER(sandbox_osd_drv) = {
155*4eea5318SMario Six .name = "sandbox_osd_drv",
156*4eea5318SMario Six .id = UCLASS_VIDEO_OSD,
157*4eea5318SMario Six .ops = &sandbox_osd_ops,
158*4eea5318SMario Six .of_match = sandbox_osd_ids,
159*4eea5318SMario Six .probe = sandbox_osd_probe,
160*4eea5318SMario Six .priv_auto_alloc_size = sizeof(struct sandbox_osd_priv),
161*4eea5318SMario Six };
162