1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2017
4  * Mario Six,  Guntermann & Drunck GmbH, mario.six@gdsys.cc
5  *
6  * based on the gdsys osd driver, which is
7  *
8  * (C) Copyright 2010
9  * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
10  */
11 
12 #include <common.h>
13 #include <command.h>
14 #include <dm.h>
15 #include <hexdump.h>
16 #include <video_osd.h>
17 #include <malloc.h>
18 
do_osd_write(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])19 static int do_osd_write(struct cmd_tbl *cmdtp, int flag, int argc,
20 			char *const argv[])
21 {
22 	struct udevice *dev;
23 	uint x, y;
24 	uint count;
25 	char *hexstr;
26 	u8 *buffer;
27 	size_t buflen;
28 	int res;
29 
30 	if (argc < 4 || (strlen(argv[3])) % 2)
31 		return CMD_RET_USAGE;
32 
33 	x = simple_strtoul(argv[1], NULL, 16);
34 	y = simple_strtoul(argv[2], NULL, 16);
35 	hexstr = argv[3];
36 	count = (argc > 4) ? simple_strtoul(argv[4], NULL, 16) : 1;
37 
38 	buflen = strlen(hexstr) / 2;
39 
40 	buffer = malloc(buflen);
41 	if (!buffer) {
42 		puts("Memory allocation failure\n");
43 		return CMD_RET_FAILURE;
44 	}
45 
46 	res = hex2bin(buffer, hexstr, buflen);
47 	if (res) {
48 		free(buffer);
49 		puts("Hexadecimal input contained invalid characters\n");
50 		return CMD_RET_FAILURE;
51 	}
52 
53 	for (uclass_first_device(UCLASS_VIDEO_OSD, &dev);
54 	     dev;
55 	     uclass_next_device(&dev)) {
56 		int res;
57 
58 		res = video_osd_set_mem(dev, x, y, buffer, buflen, count);
59 		if (res) {
60 			free(buffer);
61 			printf("Could not write to video mem on osd %s\n",
62 			       dev->name);
63 			return CMD_RET_FAILURE;
64 		}
65 	}
66 
67 	free(buffer);
68 
69 	return CMD_RET_SUCCESS;
70 }
71 
do_osd_print(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])72 static int do_osd_print(struct cmd_tbl *cmdtp, int flag, int argc,
73 			char *const argv[])
74 {
75 	struct udevice *dev;
76 	uint x, y;
77 	u8 color;
78 	char *text;
79 
80 	if (argc < 5)
81 		return CMD_RET_USAGE;
82 
83 	x = simple_strtoul(argv[1], NULL, 16);
84 	y = simple_strtoul(argv[2], NULL, 16);
85 	color = simple_strtoul(argv[3], NULL, 16);
86 	text = argv[4];
87 
88 	for (uclass_first_device(UCLASS_VIDEO_OSD, &dev);
89 	     dev;
90 	     uclass_next_device(&dev)) {
91 		int res;
92 
93 		res = video_osd_print(dev, x, y, color, text);
94 		if (res) {
95 			printf("Could not print string to osd %s\n", dev->name);
96 			return CMD_RET_FAILURE;
97 		}
98 	}
99 
100 	return CMD_RET_SUCCESS;
101 }
102 
do_osd_size(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])103 static int do_osd_size(struct cmd_tbl *cmdtp, int flag, int argc,
104 		       char *const argv[])
105 {
106 	struct udevice *dev;
107 	uint x, y;
108 
109 	if (argc < 3)
110 		return CMD_RET_USAGE;
111 
112 	x = simple_strtoul(argv[1], NULL, 16);
113 	y = simple_strtoul(argv[2], NULL, 16);
114 
115 	for (uclass_first_device(UCLASS_VIDEO_OSD, &dev);
116 	     dev;
117 	     uclass_next_device(&dev)) {
118 		int res;
119 
120 		res = video_osd_set_size(dev, x, y);
121 
122 		if (res) {
123 			printf("Could not set size on osd %s\n", dev->name);
124 			return CMD_RET_FAILURE;
125 		}
126 	}
127 
128 	return CMD_RET_SUCCESS;
129 }
130 
131 U_BOOT_CMD(
132 	osdw, 5, 0, do_osd_write,
133 	"write 16-bit hex encoded buffer to osd memory",
134 	"osdw [pos_x] [pos_y] [buffer] [count] - write 8-bit hex encoded buffer to osd memory\n"
135 );
136 
137 U_BOOT_CMD(
138 	osdp, 5, 0, do_osd_print,
139 	"write ASCII buffer to osd memory",
140 	"osdp [pos_x] [pos_y] [color] [text] - write ASCII buffer to osd memory\n"
141 );
142 
143 U_BOOT_CMD(
144 	osdsize, 3, 0, do_osd_size,
145 	"set OSD XY size in characters",
146 	"osdsize [size_x] [size_y] - set OSD XY size in characters\n"
147 );
148