blob: a931fd9d54f0199bbfdb94689840d67a84d7ccf6 [file] [log] [blame]
Rasmus Villemoescc092022020-07-06 22:01:15 +02001// SPDX-License-Identifier: GPL-2.0+
2
Rasmus Villemoescc092022020-07-06 22:01:15 +02003#include <command.h>
Simon Glass1ab16922022-07-31 12:28:48 -06004#include <display_options.h>
Rasmus Villemoescc092022020-07-06 22:01:15 +02005#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
13static 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
Simon Glass3ff49ec2021-07-24 09:03:29 -060021 reg = hextoul(argv[0], NULL);
22 len = hextoul(argv[1], NULL);
Rasmus Villemoescc092022020-07-06 22:01:15 +020023
24 if (argc == 3) {
25 u8 *addr;
26
Simon Glass3ff49ec2021-07-24 09:03:29 -060027 addr = map_sysmem(hextoul(argv[2], NULL), len);
Rasmus Villemoescc092022020-07-06 22:01:15 +020028 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
52static 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
Simon Glass3ff49ec2021-07-24 09:03:29 -060062 reg = hextoul(argv[0], NULL);
Rasmus Villemoescc092022020-07-06 22:01:15 +020063
64 if (argc == 3) {
65 u8 *addr;
66
Simon Glass3ff49ec2021-07-24 09:03:29 -060067 len = hextoul(argv[1], NULL);
68 addr = map_sysmem(hextoul(argv[2], NULL), len);
Rasmus Villemoescc092022020-07-06 22:01:15 +020069 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
105int 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)
Simon Glassff9b9032021-07-24 09:03:30 -0600133 idx = dectoul(argv[1], NULL);
Rasmus Villemoescc092022020-07-06 22:01:15 +0200134
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
158U_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);