1 /*
2  * Copyright (c) 2021 Antmicro <www.antmicro.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/sys/printk.h>
8 #include <zephyr/shell/shell.h>
9 #include <zephyr/version.h>
10 #include <stdlib.h>
11 #include <zephyr/drivers/fpga.h>
12 
parse_common_args(const struct shell * sh,char ** argv,const struct device ** dev)13 static int parse_common_args(const struct shell *sh, char **argv,
14 			     const struct device **dev)
15 {
16 	*dev = shell_device_get_binding(argv[1]);
17 	if (!*dev) {
18 		shell_error(sh, "FPGA device %s not found", argv[1]);
19 		return -ENODEV;
20 	}
21 	return 0;
22 }
23 
cmd_on(const struct shell * sh,size_t argc,char ** argv)24 static int cmd_on(const struct shell *sh, size_t argc, char **argv)
25 {
26 	const struct device *dev;
27 	int err;
28 
29 	err = parse_common_args(sh, argv, &dev);
30 	if (err < 0) {
31 		return err;
32 	}
33 
34 	shell_print(sh, "%s: turning on", dev->name);
35 
36 	err = fpga_on(dev);
37 	if (err) {
38 		shell_error(sh, "Error: %d", err);
39 	}
40 
41 	return err;
42 }
43 
cmd_off(const struct shell * sh,size_t argc,char ** argv)44 static int cmd_off(const struct shell *sh, size_t argc, char **argv)
45 {
46 	const struct device *dev;
47 	int err;
48 
49 	err = parse_common_args(sh, argv, &dev);
50 	if (err < 0) {
51 		return err;
52 	}
53 
54 	shell_print(sh, "%s: turning off", dev->name);
55 
56 	err = fpga_off(dev);
57 	if (err) {
58 		shell_error(sh, "Error: %d", err);
59 	}
60 
61 	return err;
62 }
63 
cmd_reset(const struct shell * sh,size_t argc,char ** argv)64 static int cmd_reset(const struct shell *sh, size_t argc, char **argv)
65 {
66 	const struct device *dev;
67 	int err;
68 
69 	err = parse_common_args(sh, argv, &dev);
70 	if (err < 0) {
71 		return err;
72 	}
73 
74 	shell_print(sh, "%s: resetting FPGA", dev->name);
75 
76 	err = fpga_reset(dev);
77 	if (err) {
78 		shell_error(sh, "Error: %d", err);
79 	}
80 
81 	return err;
82 }
83 
cmd_load(const struct shell * sh,size_t argc,char ** argv)84 static int cmd_load(const struct shell *sh, size_t argc, char **argv)
85 {
86 	const struct device *dev;
87 	int err;
88 
89 	err = parse_common_args(sh, argv, &dev);
90 	if (err < 0) {
91 		return err;
92 	}
93 
94 	shell_print(sh, "%s: loading bitstream", dev->name);
95 
96 	err = fpga_load(dev, (uint32_t *)strtol(argv[2], NULL, 0),
97 			(uint32_t)atoi(argv[3]));
98 	if (err) {
99 		shell_error(sh, "Error: %d", err);
100 	}
101 
102 	return err;
103 }
104 
cmd_get_status(const struct shell * sh,size_t argc,char ** argv)105 static int cmd_get_status(const struct shell *sh, size_t argc, char **argv)
106 {
107 	const struct device *dev;
108 	int err;
109 
110 	err = parse_common_args(sh, argv, &dev);
111 	if (err < 0) {
112 		return err;
113 	}
114 
115 	shell_print(sh, "%s status: %d", dev->name, fpga_get_status(dev));
116 
117 	return err;
118 }
119 
cmd_get_info(const struct shell * sh,size_t argc,char ** argv)120 static int cmd_get_info(const struct shell *sh, size_t argc, char **argv)
121 {
122 	const struct device *dev;
123 	int err;
124 
125 	err = parse_common_args(sh, argv, &dev);
126 	if (err < 0) {
127 		return err;
128 	}
129 
130 	shell_print(sh, "%s", fpga_get_info(dev));
131 
132 	return err;
133 }
134 
135 SHELL_STATIC_SUBCMD_SET_CREATE(
136 	sub_fpga, SHELL_CMD_ARG(off, NULL, "<device>", cmd_off, 2, 0),
137 	SHELL_CMD_ARG(on, NULL, "<device>", cmd_on, 2, 0),
138 	SHELL_CMD_ARG(reset, NULL, "<device>", cmd_reset, 2, 0),
139 	SHELL_CMD_ARG(load, NULL, "<device> <address> <size in bytes>",
140 		      cmd_load, 4, 0),
141 	SHELL_CMD_ARG(get_status, NULL, "<device>", cmd_get_status, 2, 0),
142 	SHELL_CMD_ARG(get_info, NULL, "<device>", cmd_get_info, 2, 0),
143 	SHELL_SUBCMD_SET_END);
144 
145 SHELL_CMD_REGISTER(fpga, &sub_fpga, "FPGA commands", NULL);
146