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