1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2013 Google, Inc
4 *
5 * (C) Copyright 2012
6 * Pavel Herrmann <morpheus.ibis@gmail.com>
7 */
8
9#include <common.h>
10#include <command.h>
11#include <dm.h>
12#include <dm-demo.h>
13#include <mapmem.h>
14#include <asm/io.h>
15
16struct udevice *demo_dev;
17
18static int do_demo_hello(struct cmd_tbl *cmdtp, int flag, int argc,
19			 char *const argv[])
20{
21	int ch = 0;
22
23	if (argc)
24		ch = *argv[0];
25
26	return demo_hello(demo_dev, ch);
27}
28
29static int do_demo_status(struct cmd_tbl *cmdtp, int flag, int argc,
30			  char *const argv[])
31{
32	int status;
33	int ret;
34
35	ret = demo_status(demo_dev, &status);
36	if (ret)
37		return ret;
38
39	printf("Status: %d\n", status);
40
41	return 0;
42}
43
44static int do_demo_light(struct cmd_tbl *cmdtp, int flag, int argc,
45			 char *const argv[])
46{
47	int light;
48	int ret;
49
50	if (argc) {
51		light = hextoul(argv[0], NULL);
52		ret = demo_set_light(demo_dev, light);
53	} else {
54		ret = demo_get_light(demo_dev);
55		if (ret >= 0) {
56			printf("Light: %x\n", ret);
57			ret = 0;
58		}
59	}
60
61	return ret;
62}
63
64int do_demo_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
65{
66	struct udevice *dev;
67	int i, ret, err = 0;
68
69	puts("Demo uclass entries:\n");
70
71	for (i = 0, ret = uclass_first_device_check(UCLASS_DEMO, &dev);
72	     dev;
73	     ret = uclass_next_device_check(&dev)) {
74		printf("entry %d - instance %08x, ops %08x, plat %08x, status %i\n",
75		       i++, (uint)map_to_sysmem(dev),
76		       (uint)map_to_sysmem(dev->driver->ops),
77		       (uint)map_to_sysmem(dev_get_plat(dev)),
78		       ret);
79		if (ret)
80			err = ret;
81	}
82
83	return cmd_process_error(cmdtp, err);
84}
85
86static struct cmd_tbl demo_commands[] = {
87	U_BOOT_CMD_MKENT(list, 0, 1, do_demo_list, "", ""),
88	U_BOOT_CMD_MKENT(hello, 2, 1, do_demo_hello, "", ""),
89	U_BOOT_CMD_MKENT(light, 2, 1, do_demo_light, "", ""),
90	U_BOOT_CMD_MKENT(status, 1, 1, do_demo_status, "", ""),
91};
92
93static int do_demo(struct cmd_tbl *cmdtp, int flag, int argc,
94		   char *const argv[])
95{
96	struct cmd_tbl *demo_cmd;
97	int devnum = 0;
98	int ret;
99
100	if (argc < 2)
101		return CMD_RET_USAGE;
102	demo_cmd = find_cmd_tbl(argv[1], demo_commands,
103				ARRAY_SIZE(demo_commands));
104	argc -= 2;
105	argv += 2;
106
107	if ((!demo_cmd || argc > demo_cmd->maxargs) ||
108	    ((demo_cmd->name[0] != 'l') && (argc < 1)))
109		return CMD_RET_USAGE;
110
111	if (argc) {
112		devnum = dectoul(argv[0], NULL);
113		ret = uclass_get_device(UCLASS_DEMO, devnum, &demo_dev);
114		if (ret)
115			return cmd_process_error(cmdtp, ret);
116		argc--;
117		argv++;
118	} else {
119		demo_dev = NULL;
120		if (demo_cmd->cmd != do_demo_list)
121			return CMD_RET_USAGE;
122	}
123
124	ret = demo_cmd->cmd(demo_cmd, flag, argc, argv);
125
126	return cmd_process_error(demo_cmd, ret);
127}
128
129U_BOOT_CMD(
130	demo,   4,      1,      do_demo,
131	"Driver model (dm) demo operations",
132	"list                     List available demo devices\n"
133	"demo hello <num> [<char>]     Say hello\n"
134	"demo light [<num>]            Set or get the lights\n"
135	"demo status <num>             Get demo device status\n"
136);
137