]>
Commit | Line | Data |
---|---|---|
803a8598 RV |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | ||
3 | #include <common.h> | |
4 | #include <command.h> | |
4e4bf944 | 5 | #include <display_options.h> |
803a8598 RV |
6 | #include <dm.h> |
7 | #include <hexdump.h> | |
8 | #include <i2c.h> | |
9 | #include <mapmem.h> | |
10 | #include <rtc.h> | |
11 | ||
12 | #define MAX_RTC_BYTES 32 | |
13 | ||
14 | static int do_rtc_read(struct udevice *dev, int argc, char * const argv[]) | |
15 | { | |
16 | u8 buf[MAX_RTC_BYTES]; | |
17 | int reg, len, ret, r; | |
18 | ||
19 | if (argc < 2 || argc > 3) | |
20 | return CMD_RET_USAGE; | |
21 | ||
7e5f460e SG |
22 | reg = hextoul(argv[0], NULL); |
23 | len = hextoul(argv[1], NULL); | |
803a8598 RV |
24 | |
25 | if (argc == 3) { | |
26 | u8 *addr; | |
27 | ||
7e5f460e | 28 | addr = map_sysmem(hextoul(argv[2], NULL), len); |
803a8598 RV |
29 | ret = dm_rtc_read(dev, reg, addr, len); |
30 | unmap_sysmem(addr); | |
31 | if (ret) { | |
32 | printf("dm_rtc_read() failed: %d\n", ret); | |
33 | return CMD_RET_FAILURE; | |
34 | } | |
35 | return CMD_RET_SUCCESS; | |
36 | } | |
37 | ||
38 | while (len) { | |
39 | r = min_t(int, len, sizeof(buf)); | |
40 | ret = dm_rtc_read(dev, reg, buf, r); | |
41 | if (ret) { | |
42 | printf("dm_rtc_read() failed: %d\n", ret); | |
43 | return CMD_RET_FAILURE; | |
44 | } | |
45 | print_buffer(reg, buf, 1, r, 0); | |
46 | len -= r; | |
47 | reg += r; | |
48 | } | |
49 | ||
50 | return CMD_RET_SUCCESS; | |
51 | } | |
52 | ||
53 | static int do_rtc_write(struct udevice *dev, int argc, char * const argv[]) | |
54 | { | |
55 | u8 buf[MAX_RTC_BYTES]; | |
56 | int reg, len, ret; | |
57 | const char *s; | |
58 | int slen; | |
59 | ||
60 | if (argc < 2 || argc > 3) | |
61 | return CMD_RET_USAGE; | |
62 | ||
7e5f460e | 63 | reg = hextoul(argv[0], NULL); |
803a8598 RV |
64 | |
65 | if (argc == 3) { | |
66 | u8 *addr; | |
67 | ||
7e5f460e SG |
68 | len = hextoul(argv[1], NULL); |
69 | addr = map_sysmem(hextoul(argv[2], NULL), len); | |
803a8598 RV |
70 | ret = dm_rtc_write(dev, reg, addr, len); |
71 | unmap_sysmem(addr); | |
72 | if (ret) { | |
73 | printf("dm_rtc_write() failed: %d\n", ret); | |
74 | return CMD_RET_FAILURE; | |
75 | } | |
76 | return CMD_RET_SUCCESS; | |
77 | } | |
78 | ||
79 | s = argv[1]; | |
80 | slen = strlen(s); | |
81 | ||
82 | if (slen % 2) { | |
83 | printf("invalid hex string\n"); | |
84 | return CMD_RET_FAILURE; | |
85 | } | |
86 | ||
87 | while (slen) { | |
88 | len = min_t(int, slen / 2, sizeof(buf)); | |
89 | if (hex2bin(buf, s, len)) { | |
90 | printf("invalid hex string\n"); | |
91 | return CMD_RET_FAILURE; | |
92 | } | |
93 | ||
94 | ret = dm_rtc_write(dev, reg, buf, len); | |
95 | if (ret) { | |
96 | printf("dm_rtc_write() failed: %d\n", ret); | |
97 | return CMD_RET_FAILURE; | |
98 | } | |
99 | s += 2 * len; | |
100 | slen -= 2 * len; | |
101 | } | |
102 | ||
103 | return CMD_RET_SUCCESS; | |
104 | } | |
105 | ||
106 | int do_rtc(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) | |
107 | { | |
108 | static int curr_rtc; | |
109 | struct udevice *dev; | |
110 | int ret, idx; | |
111 | ||
112 | if (argc < 2) | |
113 | return CMD_RET_USAGE; | |
114 | ||
115 | argc--; | |
116 | argv++; | |
117 | ||
118 | if (!strcmp(argv[0], "list")) { | |
119 | struct uclass *uc; | |
120 | ||
121 | idx = 0; | |
122 | uclass_id_foreach_dev(UCLASS_RTC, dev, uc) { | |
123 | printf("RTC #%d - %s\n", idx++, dev->name); | |
124 | } | |
125 | if (!idx) { | |
126 | printf("*** no RTC devices available ***\n"); | |
127 | return CMD_RET_FAILURE; | |
128 | } | |
129 | return CMD_RET_SUCCESS; | |
130 | } | |
131 | ||
132 | idx = curr_rtc; | |
133 | if (!strcmp(argv[0], "dev") && argc >= 2) | |
0b1284eb | 134 | idx = dectoul(argv[1], NULL); |
803a8598 RV |
135 | |
136 | ret = uclass_get_device(UCLASS_RTC, idx, &dev); | |
137 | if (ret) { | |
138 | printf("Cannot find RTC #%d: err=%d\n", idx, ret); | |
139 | return CMD_RET_FAILURE; | |
140 | } | |
141 | ||
142 | if (!strcmp(argv[0], "dev")) { | |
143 | /* Show the existing or newly selected RTC */ | |
144 | if (argc >= 2) | |
145 | curr_rtc = idx; | |
146 | printf("RTC #%d - %s\n", idx, dev->name); | |
147 | return CMD_RET_SUCCESS; | |
148 | } | |
149 | ||
150 | if (!strcmp(argv[0], "read")) | |
151 | return do_rtc_read(dev, argc - 1, argv + 1); | |
152 | ||
153 | if (!strcmp(argv[0], "write")) | |
154 | return do_rtc_write(dev, argc - 1, argv + 1); | |
155 | ||
156 | return CMD_RET_USAGE; | |
157 | } | |
158 | ||
159 | U_BOOT_CMD( | |
160 | rtc, 5, 0, do_rtc, | |
161 | "RTC subsystem", | |
162 | "list - show available rtc devices\n" | |
163 | "rtc dev [n] - show or set current rtc device\n" | |
164 | "rtc read <reg> <count> - read and display 8-bit registers starting at <reg>\n" | |
165 | "rtc read <reg> <count> <addr> - read 8-bit registers starting at <reg> to memory <addr>\n" | |
166 | "rtc write <reg> <hexstring> - write 8-bit registers starting at <reg>\n" | |
167 | "rtc write <reg> <count> <addr> - write from memory <addr> to 8-bit registers starting at <reg>\n" | |
168 | ); |