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