]> Git Repo - u-boot.git/blame - cmd/date.c
Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
[u-boot.git] / cmd / date.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
3863585b
WD
2/*
3 * (C) Copyright 2001
4 * Wolfgang Denk, DENX Software Engineering, [email protected].
3863585b
WD
5 */
6
7/*
8 * RTC, Date & Time support: get and set date & time
9 */
d678a59d 10#include <common.h>
3863585b 11#include <command.h>
f9951ead 12#include <dm.h>
3863585b 13#include <rtc.h>
0dc018ec 14#include <i2c.h>
401d1c4f 15#include <asm/global_data.h>
3863585b 16
d87080b7
WD
17DECLARE_GLOBAL_DATA_PTR;
18
bdbc1303 19static const char * const weekdays[] = {
3863585b
WD
20 "Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur",
21};
22
bdbc1303 23int mk_date (const char *, struct rtc_time *);
3863585b 24
1a1fa240
MV
25static struct rtc_time default_tm = { 0, 0, 0, 1, 1, 2000, 6, 0, 0 };
26
09140113
SG
27static int do_date(struct cmd_tbl *cmdtp, int flag, int argc,
28 char *const argv[])
3863585b
WD
29{
30 struct rtc_time tm;
31 int rcode = 0;
f9951ead 32 int old_bus __maybe_unused;
0dc018ec
SR
33
34 /* switch to correct I2C bus */
ffe38798 35#ifdef CONFIG_DM_RTC
f9951ead
SG
36 struct udevice *dev;
37
a1ae55ee 38 rcode = uclass_get_device_by_seq(UCLASS_RTC, 0, &dev);
f9951ead 39 if (rcode) {
a1ae55ee
MS
40 rcode = uclass_get_device(UCLASS_RTC, 0, &dev);
41 if (rcode) {
42 printf("Cannot find RTC: err=%d\n", rcode);
43 return CMD_RET_FAILURE;
44 }
f9951ead 45 }
55dabcc8 46#elif CONFIG_IS_ENABLED(SYS_I2C_LEGACY)
3f4978c7 47 old_bus = i2c_get_bus_num();
65cc0e2a 48 i2c_set_bus_num(CFG_SYS_RTC_BUS_NUM);
3f4978c7 49#else
0dc018ec 50 old_bus = I2C_GET_BUS();
65cc0e2a 51 I2C_SET_BUS(CFG_SYS_RTC_BUS_NUM);
3f4978c7 52#endif
3863585b
WD
53
54 switch (argc) {
55 case 2: /* set date & time */
56 if (strcmp(argv[1],"reset") == 0) {
4b9206ed 57 puts ("Reset RTC...\n");
ffe38798 58#ifdef CONFIG_DM_RTC
f9951ead
SG
59 rcode = dm_rtc_reset(dev);
60 if (!rcode)
61 rcode = dm_rtc_set(dev, &default_tm);
62#else
63 rtc_reset();
1a1fa240 64 rcode = rtc_set(&default_tm);
f9951ead 65#endif
1a1fa240
MV
66 if (rcode)
67 puts("## Failed to set date after RTC reset\n");
3863585b
WD
68 } else {
69 /* initialize tm with current time */
ffe38798 70#ifdef CONFIG_DM_RTC
f9951ead
SG
71 rcode = dm_rtc_get(dev, &tm);
72#else
73 rcode = rtc_get(&tm);
74#endif
75 if (!rcode) {
d1e23194 76 /* insert new date & time */
f9951ead 77 if (mk_date(argv[1], &tm) != 0) {
d1e23194
JCPV
78 puts ("## Bad date format\n");
79 break;
80 }
81 /* and write to RTC */
ffe38798 82#ifdef CONFIG_DM_RTC
f9951ead
SG
83 rcode = dm_rtc_set(dev, &tm);
84#else
85 rcode = rtc_set(&tm);
86#endif
87 if (rcode) {
88 printf("## Set date failed: err=%d\n",
89 rcode);
90 }
d1e23194 91 } else {
d52e3e01 92 puts("## Get date failed\n");
3863585b 93 }
3863585b 94 }
06a94b3e 95 fallthrough;
3863585b 96 case 1: /* get date & time */
ffe38798 97#ifdef CONFIG_DM_RTC
f9951ead
SG
98 rcode = dm_rtc_get(dev, &tm);
99#else
100 rcode = rtc_get(&tm);
101#endif
d1e23194 102 if (rcode) {
d52e3e01 103 puts("## Get date failed\n");
d1e23194
JCPV
104 break;
105 }
3863585b
WD
106
107 printf ("Date: %4d-%02d-%02d (%sday) Time: %2d:%02d:%02d\n",
108 tm.tm_year, tm.tm_mon, tm.tm_mday,
109 (tm.tm_wday<0 || tm.tm_wday>6) ?
8658370a 110 "unknown " : weekdays[tm.tm_wday],
3863585b
WD
111 tm.tm_hour, tm.tm_min, tm.tm_sec);
112
0dc018ec 113 break;
3863585b 114 default:
4c12eeb8 115 rcode = CMD_RET_USAGE;
3863585b 116 }
0dc018ec
SR
117
118 /* switch back to original I2C bus */
55dabcc8 119#if CONFIG_IS_ENABLED(SYS_I2C_LEGACY)
3f4978c7 120 i2c_set_bus_num(old_bus);
ffe38798 121#elif !defined(CONFIG_DM_RTC)
0dc018ec 122 I2C_SET_BUS(old_bus);
3f4978c7 123#endif
0dc018ec 124
f9951ead 125 return rcode ? CMD_RET_FAILURE : 0;
3863585b
WD
126}
127
128/*
129 * simple conversion of two-digit string with error checking
130 */
bdbc1303 131static int cnvrt2 (const char *str, int *valp)
3863585b
WD
132{
133 int val;
134
135 if ((*str < '0') || (*str > '9'))
136 return (-1);
137
138 val = *str - '0';
139
140 ++str;
141
142 if ((*str < '0') || (*str > '9'))
143 return (-1);
144
145 *valp = 10 * val + (*str - '0');
146
147 return (0);
148}
149
150/*
151 * Convert date string: MMDDhhmm[[CC]YY][.ss]
152 *
153 * Some basic checking for valid values is done, but this will not catch
154 * all possible error conditions.
155 */
bdbc1303 156int mk_date (const char *datestr, struct rtc_time *tmp)
3863585b
WD
157{
158 int len, val;
159 char *ptr;
160
44ac80e7
RK
161 ptr = strchr(datestr, '.');
162 len = strlen(datestr);
3863585b
WD
163
164 /* Set seconds */
165 if (ptr) {
166 int sec;
167
44ac80e7 168 ptr++;
3863585b
WD
169 if ((len - (ptr - datestr)) != 2)
170 return (-1);
171
44ac80e7 172 len -= 3;
3863585b
WD
173
174 if (cnvrt2 (ptr, &sec))
175 return (-1);
176
177 tmp->tm_sec = sec;
178 } else {
179 tmp->tm_sec = 0;
180 }
181
182 if (len == 12) { /* MMDDhhmmCCYY */
183 int year, century;
184
185 if (cnvrt2 (datestr+ 8, &century) ||
186 cnvrt2 (datestr+10, &year) ) {
187 return (-1);
188 }
189 tmp->tm_year = 100 * century + year;
190 } else if (len == 10) { /* MMDDhhmmYY */
191 int year, century;
192
193 century = tmp->tm_year / 100;
194 if (cnvrt2 (datestr+ 8, &year))
195 return (-1);
196 tmp->tm_year = 100 * century + year;
197 }
198
199 switch (len) {
200 case 8: /* MMDDhhmm */
201 /* fall thru */
202 case 10: /* MMDDhhmmYY */
203 /* fall thru */
204 case 12: /* MMDDhhmmCCYY */
205 if (cnvrt2 (datestr+0, &val) ||
206 val > 12) {
207 break;
208 }
209 tmp->tm_mon = val;
210 if (cnvrt2 (datestr+2, &val) ||
211 val > ((tmp->tm_mon==2) ? 29 : 31)) {
212 break;
213 }
214 tmp->tm_mday = val;
215
216 if (cnvrt2 (datestr+4, &val) ||
217 val > 23) {
218 break;
219 }
220 tmp->tm_hour = val;
221
222 if (cnvrt2 (datestr+6, &val) ||
223 val > 59) {
224 break;
225 }
226 tmp->tm_min = val;
227
228 /* calculate day of week */
199e87c3 229 rtc_calc_weekday(tmp);
3863585b
WD
230
231 return (0);
232 default:
233 break;
234 }
235
236 return (-1);
237}
238
8bde7f77
WD
239/***************************************************/
240
0d498393
WD
241U_BOOT_CMD(
242 date, 2, 1, do_date,
2fb2604d 243 "get/set/reset date & time",
8bde7f77
WD
244 "[MMDDhhmm[[CC]YY][.ss]]\ndate reset\n"
245 " - without arguments: print date & time\n"
246 " - with numeric argument: set the system date & time\n"
a89c33db 247 " - with 'reset' argument: reset the RTC"
8bde7f77 248);
This page took 0.380984 seconds and 4 git commands to generate.