]>
Commit | Line | Data |
---|---|---|
3bc0db11 BM |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * Copyright (c) 2020 Wind River Systems, Inc. | |
4 | * | |
5 | * Author: | |
6 | * Bin Meng <[email protected]> | |
7 | * | |
8 | * A command interface to access misc devices with MISC uclass driver APIs. | |
9 | */ | |
10 | ||
d678a59d | 11 | #include <common.h> |
3bc0db11 BM |
12 | #include <command.h> |
13 | #include <dm.h> | |
14 | #include <errno.h> | |
15 | #include <misc.h> | |
16 | ||
17 | enum misc_op { | |
18 | MISC_OP_READ, | |
19 | MISC_OP_WRITE | |
20 | }; | |
21 | ||
22 | static char *misc_op_str[] = { | |
23 | "read", | |
24 | "write" | |
25 | }; | |
26 | ||
27 | static int do_misc_list(struct cmd_tbl *cmdtp, int flag, | |
28 | int argc, char *const argv[]) | |
29 | { | |
30 | struct udevice *dev; | |
31 | ||
32 | printf("Device Index Driver\n"); | |
33 | printf("-------------------------------------\n"); | |
34 | for (uclass_first_device(UCLASS_MISC, &dev); | |
35 | dev; | |
36 | uclass_next_device(&dev)) { | |
8b85dfc6 | 37 | printf("%-20s %5d %10s\n", dev->name, dev_seq(dev), |
3bc0db11 BM |
38 | dev->driver->name); |
39 | } | |
40 | ||
41 | return 0; | |
42 | } | |
43 | ||
44 | static int do_misc_op(struct cmd_tbl *cmdtp, int flag, | |
45 | int argc, char *const argv[], enum misc_op op) | |
46 | { | |
3bc0db11 BM |
47 | struct udevice *dev; |
48 | int offset; | |
49 | void *buf; | |
50 | int size; | |
51 | int ret; | |
52 | ||
53 | ret = uclass_get_device_by_name(UCLASS_MISC, argv[0], &dev); | |
54 | if (ret) { | |
55 | printf("Unable to find device %s\n", argv[0]); | |
56 | return ret; | |
57 | } | |
58 | ||
7e5f460e SG |
59 | offset = hextoul(argv[1], NULL); |
60 | buf = (void *)hextoul(argv[2], NULL); | |
61 | size = hextoul(argv[3], NULL); | |
3bc0db11 BM |
62 | |
63 | if (op == MISC_OP_READ) | |
c4645fc8 | 64 | ret = misc_read(dev, offset, buf, size); |
3bc0db11 | 65 | else |
c4645fc8 | 66 | ret = misc_write(dev, offset, buf, size); |
3bc0db11 | 67 | |
3bc0db11 BM |
68 | if (ret < 0) { |
69 | if (ret == -ENOSYS) { | |
70 | printf("The device does not support %s\n", | |
71 | misc_op_str[op]); | |
72 | ret = 0; | |
73 | } | |
74 | } else { | |
75 | if (ret == size) | |
76 | ret = 0; | |
77 | else | |
78 | printf("Partially %s %d bytes\n", misc_op_str[op], ret); | |
79 | } | |
80 | ||
81 | return ret; | |
82 | } | |
83 | ||
84 | static int do_misc_read(struct cmd_tbl *cmdtp, int flag, | |
85 | int argc, char *const argv[]) | |
86 | { | |
87 | return do_misc_op(cmdtp, flag, argc, argv, MISC_OP_READ); | |
88 | } | |
89 | ||
90 | static int do_misc_write(struct cmd_tbl *cmdtp, int flag, | |
91 | int argc, char *const argv[]) | |
92 | { | |
93 | return do_misc_op(cmdtp, flag, argc, argv, MISC_OP_WRITE); | |
94 | } | |
95 | ||
96 | static struct cmd_tbl misc_commands[] = { | |
97 | U_BOOT_CMD_MKENT(list, 0, 1, do_misc_list, "", ""), | |
98 | U_BOOT_CMD_MKENT(read, 4, 1, do_misc_read, "", ""), | |
99 | U_BOOT_CMD_MKENT(write, 4, 1, do_misc_write, "", ""), | |
100 | }; | |
101 | ||
102 | static int do_misc(struct cmd_tbl *cmdtp, int flag, | |
103 | int argc, char *const argv[]) | |
104 | { | |
105 | struct cmd_tbl *misc_cmd; | |
106 | int ret; | |
107 | ||
108 | if (argc < 2) | |
109 | return CMD_RET_USAGE; | |
110 | misc_cmd = find_cmd_tbl(argv[1], misc_commands, | |
111 | ARRAY_SIZE(misc_commands)); | |
112 | argc -= 2; | |
113 | argv += 2; | |
114 | if (!misc_cmd || argc != misc_cmd->maxargs) | |
115 | return CMD_RET_USAGE; | |
116 | ||
117 | ret = misc_cmd->cmd(misc_cmd, flag, argc, argv); | |
118 | ||
119 | return cmd_process_error(misc_cmd, ret); | |
120 | } | |
121 | ||
122 | U_BOOT_CMD( | |
123 | misc, 6, 1, do_misc, | |
124 | "Access miscellaneous devices with MISC uclass driver APIs", | |
125 | "list - list all miscellaneous devices\n" | |
126 | "misc read name offset addr len - read `len' bytes starting at\n" | |
127 | " `offset' of device `name'\n" | |
128 | " to memory at `addr'\n" | |
129 | "misc write name offset addr len - write `len' bytes starting at\n" | |
130 | " `offset' of device `name'\n" | |
131 | " from memory at `addr'" | |
132 | ); |