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