From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from metis.ext.pengutronix.de ([2001:6f8:1178:4:290:27ff:fe1d:cc33]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1X80yC-0001Mi-Qu for barebox@lists.infradead.org; Fri, 18 Jul 2014 05:44:37 +0000 Date: Fri, 18 Jul 2014 07:44:13 +0200 From: Sascha Hauer Message-ID: <20140718054413.GL23235@pengutronix.de> References: <1405370916-6828-1-git-send-email-antonynpavlov@gmail.com> <1405370916-6828-5-git-send-email-antonynpavlov@gmail.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1405370916-6828-5-git-send-email-antonynpavlov@gmail.com> List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "barebox" Errors-To: barebox-bounces+u.kleine-koenig=pengutronix.de@lists.infradead.org Subject: Re: [RFC v3 4/5] commands: add hwclock To: Antony Pavlov Cc: barebox@lists.infradead.org On Tue, Jul 15, 2014 at 12:48:35AM +0400, Antony Pavlov wrote: > The hwclock command allows to query or set the hardware clock (RTC). > > Signed-off-by: Antony Pavlov > --- > commands/Kconfig | 8 +++ > commands/Makefile | 1 + > commands/hwclock.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 160 insertions(+) > > diff --git a/commands/Kconfig b/commands/Kconfig > index 61816f5..6a75f85 100644 > --- a/commands/Kconfig > +++ b/commands/Kconfig > @@ -1691,6 +1691,14 @@ config CMD_GPIO > > Usage: gpio_set_value GPIO VALUE > > +config CMD_HWCLOCK > + bool > + depends on RTC_CLASS > + prompt "hwclock command" > + default y > + help > + The hwclock command allows to query or set the hardware clock (RTC). > + > config CMD_I2C > bool > depends on I2C > diff --git a/commands/Makefile b/commands/Makefile > index d42aca5..44dd9d4 100644 > --- a/commands/Makefile > +++ b/commands/Makefile > @@ -100,3 +100,4 @@ obj-$(CONFIG_CMD_MENUTREE) += menutree.o > obj-$(CONFIG_CMD_2048) += 2048.o > obj-$(CONFIG_CMD_REGULATOR) += regulator.o > obj-$(CONFIG_CMD_LSPCI) += lspci.o > +obj-$(CONFIG_CMD_HWCLOCK) += hwclock.o > diff --git a/commands/hwclock.c b/commands/hwclock.c > new file mode 100644 > index 0000000..511973a > --- /dev/null > +++ b/commands/hwclock.c > @@ -0,0 +1,151 @@ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +static char *strchrnul(const char *s, int c) > +{ > + while (*s != '\0' && *s != c) > + s++; > + > + return (char *)s; > +} > + > +static int sscanf_two_digits(char *s, int *res) > +{ > + char buf[3]; > + unsigned long t; > + > + if (!isdigit(s[0]) || !isdigit(s[1])) { > + return -EINVAL; > + } > + > + buf[0] = s[0]; > + buf[1] = s[1]; > + buf[2] = '\0'; > + > + t = simple_strtoul(buf, NULL, 10); > + *res = t; > + > + return 0; > +} > + > +static int parse_datestr(char *date_str, struct rtc_time *ptm) > +{ > + char end = '\0'; > + int len = strchrnul(date_str, '.') - date_str; > + int year; > + > + /* ccyymmddHHMM[.SS] */ > + if (len != 12) { > + return -EINVAL; > + } > + > + if (sscanf_two_digits(date_str, &year) || > + sscanf_two_digits(&date_str[2], &ptm->tm_year)) { > + return -EINVAL; > + } > + > + ptm->tm_year = year * 100 + ptm->tm_year; > + > + /* Adjust years */ > + ptm->tm_year -= 1900; > + > + if (sscanf_two_digits(&date_str[4], &ptm->tm_mon) || > + sscanf_two_digits(&date_str[6], &ptm->tm_mday) || > + sscanf_two_digits(&date_str[8], &ptm->tm_hour) || > + sscanf_two_digits(&date_str[10], &ptm->tm_min)) { > + return -EINVAL; > + } > + > + /* Adjust month from 1-12 to 0-11 */ > + ptm->tm_mon -= 1; > + > + end = date_str[12]; > + > + if (end == '.') { > + /* xxx.SS */ > + if (!sscanf_two_digits(&date_str[13], &ptm->tm_sec)) { > + end = '\0'; > + } > + /* else end != NUL and we error out */ > + } > + > + if (end != '\0') { > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int do_hwclock(int argc, char *argv[]) > +{ > + struct rtc_device *r; > + struct rtc_time tm; > + struct rtc_time stm; > + char rtc_name[16] = "rtc0"; > + char *env_name = NULL; > + int opt; > + int set = 0; > + > + while ((opt = getopt(argc, argv, "f:s:e:")) > 0) { > + switch (opt) { > + case 'f': > + strncpy(rtc_name, optarg, 16); > + break; > + case 's': > + memset(&stm, 0, sizeof(stm)); > + parse_datestr(optarg, &stm); > + set = 1; > + break; > + case 'e': > + env_name = optarg; > + break; > + } > + } > + > + r = rtc_lookup(rtc_name); > + if (IS_ERR(r)) > + return PTR_ERR(r); > + > + if (set) { > + rtc_set_time(r, &stm); > + return 0; > + } > + > + rtc_read_time(r, &tm); > + > + if (env_name) { > + unsigned long time; > + char t[12]; > + > + rtc_tm_to_time(&tm, &time); > + snprintf(t, 12, "%lu", time); > + setenv(env_name, t); I thought more about a globalvar_add(), like globalvar.date, so that no command has to be executed to get the date. But then again maybe it's better to have it in a command since it allows us to add different formats without much hassle. > + } else { > + printf("%02d:%02d:%02d %02d-%02d-%04d\n", > + tm.tm_hour, tm.tm_min, tm.tm_sec, > + tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900); > + } > + > + return 0; > +} > + > +BAREBOX_CMD_HELP_START(hwclock) > +BAREBOX_CMD_HELP_TEXT("Options:") > +BAREBOX_CMD_HELP_OPT ("-f NAME\t\t\t", "RTC device name (default rtc0)") > +BAREBOX_CMD_HELP_OPT ("-e VARNAME\t\t", "store RTC readout into variable VARNAME") > +BAREBOX_CMD_HELP_OPT ("-s ccyymmddHHMM[.SS]\t", "set time") It's much more logical to have the year first, but the format documented in 'man date' is MMDDhhmm[[CC]YY][.ss]. Of course we are free to choose another format, but maybe we should rather use a format someone other uses aswell? Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox