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