xref: /openbmc/u-boot/cmd/osd.c (revision 592cd5de)
1*3bf65cb5SMario Six // SPDX-License-Identifier: GPL-2.0+
2*3bf65cb5SMario Six /*
3*3bf65cb5SMario Six  * (C) Copyright 2017
4*3bf65cb5SMario Six  * Mario Six,  Guntermann & Drunck GmbH, mario.six@gdsys.cc
5*3bf65cb5SMario Six  *
6*3bf65cb5SMario Six  * based on the gdsys osd driver, which is
7*3bf65cb5SMario Six  *
8*3bf65cb5SMario Six  * (C) Copyright 2010
9*3bf65cb5SMario Six  * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
10*3bf65cb5SMario Six  */
11*3bf65cb5SMario Six 
12*3bf65cb5SMario Six #include <common.h>
13*3bf65cb5SMario Six #include <dm.h>
14*3bf65cb5SMario Six #include <hexdump.h>
15*3bf65cb5SMario Six #include <video_osd.h>
16*3bf65cb5SMario Six #include <malloc.h>
17*3bf65cb5SMario Six 
18*3bf65cb5SMario Six /* Container for selected OSD device */
19*3bf65cb5SMario Six static struct udevice *osd_cur;
20*3bf65cb5SMario Six 
21*3bf65cb5SMario Six /**
22*3bf65cb5SMario Six  * cmd_osd_set_osd_num() - Set the OSD selected for operation
23*3bf65cb5SMario Six  *
24*3bf65cb5SMario Six  * Set the OSD device, which will be used by all subsequent OSD commands.
25*3bf65cb5SMario Six  *
26*3bf65cb5SMario Six  * Devices are identified by their uclass sequence number (as listed by 'osd
27*3bf65cb5SMario Six  * show').
28*3bf65cb5SMario Six  *
29*3bf65cb5SMario Six  * @osdnum: The OSD device to be selected, identified by its sequence number.
30*3bf65cb5SMario Six  * Return: 0 if OK, -ve on error
31*3bf65cb5SMario Six  */
cmd_osd_set_osd_num(unsigned int osdnum)32*3bf65cb5SMario Six static int cmd_osd_set_osd_num(unsigned int osdnum)
33*3bf65cb5SMario Six {
34*3bf65cb5SMario Six 	struct udevice *osd;
35*3bf65cb5SMario Six 	int res;
36*3bf65cb5SMario Six 
37*3bf65cb5SMario Six 	res = uclass_get_device_by_seq(UCLASS_VIDEO_OSD, osdnum, &osd);
38*3bf65cb5SMario Six 	if (res) {
39*3bf65cb5SMario Six 		printf("%s: No OSD %u (err = %d)\n", __func__, osdnum, res);
40*3bf65cb5SMario Six 		return res;
41*3bf65cb5SMario Six 	}
42*3bf65cb5SMario Six 	osd_cur = osd;
43*3bf65cb5SMario Six 
44*3bf65cb5SMario Six 	return 0;
45*3bf65cb5SMario Six }
46*3bf65cb5SMario Six 
47*3bf65cb5SMario Six /**
48*3bf65cb5SMario Six  * osd_get_osd_cur() - Get the selected OSD device
49*3bf65cb5SMario Six  *
50*3bf65cb5SMario Six  * Get the OSD device that is used by all OSD commands.
51*3bf65cb5SMario Six  *
52*3bf65cb5SMario Six  * @osdp: Pointer to structure that will receive the currently selected OSD
53*3bf65cb5SMario Six  *	  device.
54*3bf65cb5SMario Six  * Return: 0 if OK, -ve on error
55*3bf65cb5SMario Six  */
osd_get_osd_cur(struct udevice ** osdp)56*3bf65cb5SMario Six static int osd_get_osd_cur(struct udevice **osdp)
57*3bf65cb5SMario Six {
58*3bf65cb5SMario Six 	if (!osd_cur) {
59*3bf65cb5SMario Six 		puts("No osd selected\n");
60*3bf65cb5SMario Six 		return -ENODEV;
61*3bf65cb5SMario Six 	}
62*3bf65cb5SMario Six 	*osdp = osd_cur;
63*3bf65cb5SMario Six 
64*3bf65cb5SMario Six 	return 0;
65*3bf65cb5SMario Six }
66*3bf65cb5SMario Six 
67*3bf65cb5SMario Six /**
68*3bf65cb5SMario Six  * show_osd() - Display information about a OSD device
69*3bf65cb5SMario Six  *
70*3bf65cb5SMario Six  * Display a device's ID (sequence number), and whether it is active (i.e.
71*3bf65cb5SMario Six  * probed) or not.
72*3bf65cb5SMario Six  *
73*3bf65cb5SMario Six  * @osd: OSD device to print information for
74*3bf65cb5SMario Six  */
show_osd(struct udevice * osd)75*3bf65cb5SMario Six static void show_osd(struct udevice *osd)
76*3bf65cb5SMario Six {
77*3bf65cb5SMario Six 	printf("OSD %d:\t%s", osd->req_seq, osd->name);
78*3bf65cb5SMario Six 	if (device_active(osd))
79*3bf65cb5SMario Six 		printf("  (active %d)", osd->seq);
80*3bf65cb5SMario Six 	printf("\n");
81*3bf65cb5SMario Six }
82*3bf65cb5SMario Six 
do_osd_write(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])83*3bf65cb5SMario Six static int do_osd_write(cmd_tbl_t *cmdtp, int flag, int argc,
84*3bf65cb5SMario Six 			char * const argv[])
85*3bf65cb5SMario Six {
86*3bf65cb5SMario Six 	uint x, y;
87*3bf65cb5SMario Six 	uint count;
88*3bf65cb5SMario Six 	char *hexstr;
89*3bf65cb5SMario Six 	u8 *buffer;
90*3bf65cb5SMario Six 	size_t buflen;
91*3bf65cb5SMario Six 	int res;
92*3bf65cb5SMario Six 
93*3bf65cb5SMario Six 	if (argc < 4 || (strlen(argv[3]) % 2))
94*3bf65cb5SMario Six 		return CMD_RET_USAGE;
95*3bf65cb5SMario Six 
96*3bf65cb5SMario Six 	if (!osd_cur) {
97*3bf65cb5SMario Six 		puts("No osd selected\n");
98*3bf65cb5SMario Six 		return CMD_RET_FAILURE;
99*3bf65cb5SMario Six 	}
100*3bf65cb5SMario Six 
101*3bf65cb5SMario Six 	x = simple_strtoul(argv[1], NULL, 16);
102*3bf65cb5SMario Six 	y = simple_strtoul(argv[2], NULL, 16);
103*3bf65cb5SMario Six 	hexstr = argv[3];
104*3bf65cb5SMario Six 	count = (argc > 4) ? simple_strtoul(argv[4], NULL, 16) : 1;
105*3bf65cb5SMario Six 
106*3bf65cb5SMario Six 	buflen = strlen(hexstr) / 2;
107*3bf65cb5SMario Six 
108*3bf65cb5SMario Six 	buffer = malloc(buflen);
109*3bf65cb5SMario Six 	if (!buffer) {
110*3bf65cb5SMario Six 		puts("Memory allocation failure\n");
111*3bf65cb5SMario Six 		return CMD_RET_FAILURE;
112*3bf65cb5SMario Six 	}
113*3bf65cb5SMario Six 
114*3bf65cb5SMario Six 	res = hex2bin(buffer, hexstr, buflen);
115*3bf65cb5SMario Six 	if (res) {
116*3bf65cb5SMario Six 		free(buffer);
117*3bf65cb5SMario Six 		puts("Hexadecimal input contained invalid characters\n");
118*3bf65cb5SMario Six 		return CMD_RET_FAILURE;
119*3bf65cb5SMario Six 	}
120*3bf65cb5SMario Six 
121*3bf65cb5SMario Six 	res = video_osd_set_mem(osd_cur, x, y, buffer, buflen, count);
122*3bf65cb5SMario Six 	if (res) {
123*3bf65cb5SMario Six 		free(buffer);
124*3bf65cb5SMario Six 		printf("%s: Could not write to video mem\n",
125*3bf65cb5SMario Six 		       osd_cur->name);
126*3bf65cb5SMario Six 		return CMD_RET_FAILURE;
127*3bf65cb5SMario Six 	}
128*3bf65cb5SMario Six 
129*3bf65cb5SMario Six 	free(buffer);
130*3bf65cb5SMario Six 
131*3bf65cb5SMario Six 	return CMD_RET_SUCCESS;
132*3bf65cb5SMario Six }
133*3bf65cb5SMario Six 
do_osd_print(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])134*3bf65cb5SMario Six static int do_osd_print(cmd_tbl_t *cmdtp, int flag, int argc,
135*3bf65cb5SMario Six 			char * const argv[])
136*3bf65cb5SMario Six {
137*3bf65cb5SMario Six 	uint x, y;
138*3bf65cb5SMario Six 	u8 color;
139*3bf65cb5SMario Six 	char *text;
140*3bf65cb5SMario Six 	int res;
141*3bf65cb5SMario Six 
142*3bf65cb5SMario Six 	if (argc < 5)
143*3bf65cb5SMario Six 		return CMD_RET_USAGE;
144*3bf65cb5SMario Six 
145*3bf65cb5SMario Six 	if (!osd_cur) {
146*3bf65cb5SMario Six 		puts("No osd selected\n");
147*3bf65cb5SMario Six 		return CMD_RET_FAILURE;
148*3bf65cb5SMario Six 	}
149*3bf65cb5SMario Six 
150*3bf65cb5SMario Six 	x = simple_strtoul(argv[1], NULL, 16);
151*3bf65cb5SMario Six 	y = simple_strtoul(argv[2], NULL, 16);
152*3bf65cb5SMario Six 	color = simple_strtoul(argv[3], NULL, 16);
153*3bf65cb5SMario Six 	text = argv[4];
154*3bf65cb5SMario Six 
155*3bf65cb5SMario Six 	res = video_osd_print(osd_cur, x, y, color, text);
156*3bf65cb5SMario Six 	if (res) {
157*3bf65cb5SMario Six 		printf("Could not print string to osd %s\n", osd_cur->name);
158*3bf65cb5SMario Six 		return CMD_RET_FAILURE;
159*3bf65cb5SMario Six 	}
160*3bf65cb5SMario Six 
161*3bf65cb5SMario Six 	return CMD_RET_SUCCESS;
162*3bf65cb5SMario Six }
163*3bf65cb5SMario Six 
do_osd_size(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])164*3bf65cb5SMario Six static int do_osd_size(cmd_tbl_t *cmdtp, int flag, int argc,
165*3bf65cb5SMario Six 		       char * const argv[])
166*3bf65cb5SMario Six {
167*3bf65cb5SMario Six 	uint x, y;
168*3bf65cb5SMario Six 	int res;
169*3bf65cb5SMario Six 
170*3bf65cb5SMario Six 	if (argc < 3)
171*3bf65cb5SMario Six 		return CMD_RET_USAGE;
172*3bf65cb5SMario Six 
173*3bf65cb5SMario Six 	if (!osd_cur) {
174*3bf65cb5SMario Six 		puts("No osd selected\n");
175*3bf65cb5SMario Six 		return CMD_RET_FAILURE;
176*3bf65cb5SMario Six 	}
177*3bf65cb5SMario Six 
178*3bf65cb5SMario Six 	x = simple_strtoul(argv[1], NULL, 16);
179*3bf65cb5SMario Six 	y = simple_strtoul(argv[2], NULL, 16);
180*3bf65cb5SMario Six 
181*3bf65cb5SMario Six 	res = video_osd_set_size(osd_cur, x, y);
182*3bf65cb5SMario Six 	if (res) {
183*3bf65cb5SMario Six 		printf("Could not set size on osd %s\n", osd_cur->name);
184*3bf65cb5SMario Six 		return CMD_RET_FAILURE;
185*3bf65cb5SMario Six 	}
186*3bf65cb5SMario Six 
187*3bf65cb5SMario Six 	return CMD_RET_SUCCESS;
188*3bf65cb5SMario Six }
189*3bf65cb5SMario Six 
do_show_osd(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])190*3bf65cb5SMario Six static int do_show_osd(cmd_tbl_t *cmdtp, int flag, int argc,
191*3bf65cb5SMario Six 		       char * const argv[])
192*3bf65cb5SMario Six {
193*3bf65cb5SMario Six 	struct udevice *osd;
194*3bf65cb5SMario Six 
195*3bf65cb5SMario Six 	if (argc == 1) {
196*3bf65cb5SMario Six 		/* show all OSDs */
197*3bf65cb5SMario Six 		struct uclass *uc;
198*3bf65cb5SMario Six 		int res;
199*3bf65cb5SMario Six 
200*3bf65cb5SMario Six 		res = uclass_get(UCLASS_VIDEO_OSD, &uc);
201*3bf65cb5SMario Six 		if (res) {
202*3bf65cb5SMario Six 			printf("Error while getting OSD uclass (err=%d)\n",
203*3bf65cb5SMario Six 			       res);
204*3bf65cb5SMario Six 			return CMD_RET_FAILURE;
205*3bf65cb5SMario Six 		}
206*3bf65cb5SMario Six 
207*3bf65cb5SMario Six 		uclass_foreach_dev(osd, uc)
208*3bf65cb5SMario Six 			show_osd(osd);
209*3bf65cb5SMario Six 	} else {
210*3bf65cb5SMario Six 		int i, res;
211*3bf65cb5SMario Six 
212*3bf65cb5SMario Six 		/* show specific OSD */
213*3bf65cb5SMario Six 		i = simple_strtoul(argv[1], NULL, 10);
214*3bf65cb5SMario Six 
215*3bf65cb5SMario Six 		res = uclass_get_device_by_seq(UCLASS_VIDEO_OSD, i, &osd);
216*3bf65cb5SMario Six 		if (res) {
217*3bf65cb5SMario Six 			printf("Invalid osd %d: err=%d\n", i, res);
218*3bf65cb5SMario Six 			return CMD_RET_FAILURE;
219*3bf65cb5SMario Six 		}
220*3bf65cb5SMario Six 		show_osd(osd);
221*3bf65cb5SMario Six 	}
222*3bf65cb5SMario Six 
223*3bf65cb5SMario Six 	return CMD_RET_SUCCESS;
224*3bf65cb5SMario Six }
225*3bf65cb5SMario Six 
do_osd_num(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])226*3bf65cb5SMario Six static int do_osd_num(cmd_tbl_t *cmdtp, int flag, int argc,
227*3bf65cb5SMario Six 		      char * const argv[])
228*3bf65cb5SMario Six {
229*3bf65cb5SMario Six 	int osd_no;
230*3bf65cb5SMario Six 	int res = 0;
231*3bf65cb5SMario Six 
232*3bf65cb5SMario Six 	if (argc == 1) {
233*3bf65cb5SMario Six 		/* querying current setting */
234*3bf65cb5SMario Six 		struct udevice *osd;
235*3bf65cb5SMario Six 
236*3bf65cb5SMario Six 		if (!osd_get_osd_cur(&osd))
237*3bf65cb5SMario Six 			osd_no = osd->seq;
238*3bf65cb5SMario Six 		else
239*3bf65cb5SMario Six 			osd_no = -1;
240*3bf65cb5SMario Six 		printf("Current osd is %d\n", osd_no);
241*3bf65cb5SMario Six 	} else {
242*3bf65cb5SMario Six 		osd_no = simple_strtoul(argv[1], NULL, 10);
243*3bf65cb5SMario Six 		printf("Setting osd to %d\n", osd_no);
244*3bf65cb5SMario Six 
245*3bf65cb5SMario Six 		res = cmd_osd_set_osd_num(osd_no);
246*3bf65cb5SMario Six 		if (res)
247*3bf65cb5SMario Six 			printf("Failure changing osd number (err = %d)\n", res);
248*3bf65cb5SMario Six 	}
249*3bf65cb5SMario Six 
250*3bf65cb5SMario Six 	return res ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
251*3bf65cb5SMario Six }
252*3bf65cb5SMario Six 
253*3bf65cb5SMario Six static cmd_tbl_t cmd_osd_sub[] = {
254*3bf65cb5SMario Six 	U_BOOT_CMD_MKENT(show, 1, 1, do_show_osd, "", ""),
255*3bf65cb5SMario Six 	U_BOOT_CMD_MKENT(dev, 1, 1, do_osd_num, "", ""),
256*3bf65cb5SMario Six 	U_BOOT_CMD_MKENT(write, 4, 1, do_osd_write, "", ""),
257*3bf65cb5SMario Six 	U_BOOT_CMD_MKENT(print, 4, 1, do_osd_print, "", ""),
258*3bf65cb5SMario Six 	U_BOOT_CMD_MKENT(size, 2, 1, do_osd_size, "", ""),
259*3bf65cb5SMario Six };
260*3bf65cb5SMario Six 
do_osd(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])261*3bf65cb5SMario Six static int do_osd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
262*3bf65cb5SMario Six {
263*3bf65cb5SMario Six 	cmd_tbl_t *c;
264*3bf65cb5SMario Six 
265*3bf65cb5SMario Six 	if (argc < 2)
266*3bf65cb5SMario Six 		return CMD_RET_USAGE;
267*3bf65cb5SMario Six 
268*3bf65cb5SMario Six 	/* Strip off leading 'osd' command argument */
269*3bf65cb5SMario Six 	argc--;
270*3bf65cb5SMario Six 	argv++;
271*3bf65cb5SMario Six 
272*3bf65cb5SMario Six 	c = find_cmd_tbl(argv[0], &cmd_osd_sub[0], ARRAY_SIZE(cmd_osd_sub));
273*3bf65cb5SMario Six 
274*3bf65cb5SMario Six 	if (c)
275*3bf65cb5SMario Six 		return c->cmd(cmdtp, flag, argc, argv);
276*3bf65cb5SMario Six 	else
277*3bf65cb5SMario Six 		return CMD_RET_USAGE;
278*3bf65cb5SMario Six }
279*3bf65cb5SMario Six 
280*3bf65cb5SMario Six static char osd_help_text[] =
281*3bf65cb5SMario Six 	"show  - show OSD info\n"
282*3bf65cb5SMario Six 	"osd dev [dev] - show or set current OSD\n"
283*3bf65cb5SMario Six 	"write [pos_x] [pos_y] [buffer] [count] - write 8-bit hex encoded buffer to osd memory at a given position\n"
284*3bf65cb5SMario Six 	"print [pos_x] [pos_y] [color] [text] - write ASCII buffer (given by text data and driver-specific color information) to osd memory\n"
285*3bf65cb5SMario Six 	"size [size_x] [size_y] - set OSD XY size in characters\n";
286*3bf65cb5SMario Six 
287*3bf65cb5SMario Six U_BOOT_CMD(
288*3bf65cb5SMario Six 	osd, 6, 1, do_osd,
289*3bf65cb5SMario Six 	"OSD sub-system",
290*3bf65cb5SMario Six 	osd_help_text
291*3bf65cb5SMario Six );
292