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