]> Untitled Git - hvrtc.git/commitdiff
Add Battery backup voltage level get/set
authorHugo Villeneuve <hvilleneuve@dimonoff.com>
Mon, 9 Mar 2026 19:31:22 +0000 (15:31 -0400)
committerHugo Villeneuve <hvilleneuve@dimonoff.com>
Tue, 10 Mar 2026 19:34:44 +0000 (15:34 -0400)
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
src/main.c
src/options.c
src/options.h

index 2c6b453a4c5e578d446b0aecddf7a4e5aa4f8768..38c2d951ebb38f96bb2ae201298500f96e033d90 100644 (file)
@@ -70,8 +70,6 @@ static int rtc_param_set_bsm(int fd, int value)
        par.param = RTC_PARAM_BACKUP_SWITCH_MODE;
        par.uvalue = value;
 
-       printf("Set backup switch mode to: $%02X\n", value);
-
        ret = ioctl(fd, RTC_PARAM_SET, &par);
        if (ret < 0) {
                perror("set RTC_PARAM_BACKUP_SWITCH_MODE");
@@ -81,6 +79,64 @@ static int rtc_param_set_bsm(int fd, int value)
        return 0;
 }
 
+static int rtc_param_get_vl_backup(int fd)
+{
+       const char *prefix = "Backup voltage:";
+       unsigned long tmp;
+       int voltage_good;
+       int ret;
+
+       ret = ioctl(fd, RTC_VL_READ, &tmp);
+       if (ret < 0) {
+               perror("get RTC_VL_READ");
+               return ret;
+       }
+
+       voltage_good = true;
+
+       if (tmp & RTC_VL_DATA_INVALID) {
+               printf("%s too low, RTC data is invalid\n", prefix);
+               voltage_good = false;
+       }
+
+       if (tmp & RTC_VL_BACKUP_LOW) {
+               printf("%s low, check/replace RTC battery\n", prefix);
+               voltage_good = false;
+       }
+
+       if (tmp & RTC_VL_BACKUP_EMPTY) {
+               printf("%s empty or not present\n", prefix);
+               voltage_good = false;
+       }
+
+       if (tmp & RTC_VL_ACCURACY_LOW) {
+               printf("%s low, RTC accuracy is reduced\n", prefix);
+               voltage_good = false;
+       }
+
+       if (voltage_good)
+               printf("%s good\n", prefix);
+
+       if (tmp & RTC_VL_BACKUP_SWITCH)
+               printf("%s switchover event detected\n", prefix);
+
+       return 0;
+}
+
+static int rtc_param_clear_vl_backup(int fd)
+{
+       struct rtc_param par;
+       int ret;
+
+       ret = ioctl(fd, RTC_VL_CLR, &par);
+       if (ret < 0) {
+               perror("get RTC_VL_CLR");
+               return ret;
+       }
+
+       return 0;
+}
+
 static int rtc_test_uie(int fd)
 {
        unsigned long data;
@@ -366,6 +422,18 @@ main(int argc, char **argv)
                }
        }
 
+       if (options.vl_backup) {
+               rc = rtc_param_get_vl_backup(fd);
+               if (rc < 0)
+                       exit(rc);
+       }
+
+       if (options.clear) {
+               rc = rtc_param_clear_vl_backup(fd);
+               if (rc < 0)
+                       exit(rc);
+       }
+
        if (options.test) {
                rc = rtc_test(fd);
                if (rc < 0)
index e0ee934d2b96a7ece69e3dd806e39a2b9a3992e6..930ba0f0a5aa48c5074f9e68e14d03ad1d5449cf 100644 (file)
@@ -16,6 +16,7 @@
 #include <stdlib.h>
 #include <argp.h>
 #include <stdarg.h> /* va_start */
+#include <linux/rtc.h>
 
 #if STDC_HEADERS
 #  include <string.h>
@@ -48,11 +49,20 @@ static const char args_doc[] = "";
  */
 #define USAGE_KEY 0x123
 
+#define ARGP_BSM_STR                                                   \
+       "    disabled RTC_BSM_DISABLED\n"                               \
+       "    direct   RTC_BSM_DIRECT\n"                                 \
+       "    level    RTC_BSM_LEVEL\n"                                  \
+       "    standby  RTC_BSM_STANDBY"
+
 /* The options we understand. */
 static struct argp_option argp_options[] = {
-       {"bsm",   'b', "value", OPTION_ARG_OPTIONAL, "Get/Set  Backup Switch Mode (BSM)", 0},
-       {"dev",   'd', "path", 0, "RTC device path (optional)", 0},
+       {"bsm",   'b', "value",   OPTION_ARG_OPTIONAL, "Get/Set Backup Switch Mode (BSM):", 0},
+       {0,       0,   0,         0,                   ARGP_BSM_STR, 0},
+       {"clear", 'c', 0,         0, "Clear \"voltage low\" event", 0},
+       {"dev",   'd', "path",    0, "RTC device path (optional)", 0},
        {"test",  't', 0,         0, "Test RTC", 0},
+       {"voltage-level", 'v', 0, 0, "Get battery backup voltage level", 0},
        /*
         * Add -h manually; OPTION_HIDDEN prevents it from appearing twice in --help.
         * This must be listed after all other options, to prevent an empty line.
@@ -87,15 +97,19 @@ void log_fail(const char *format, ...)
 }
 
 static void
-decode_int(char *arg, struct argp_state *state, int *dest)
+decode_bsm(char *arg, struct argp_state *state)
 {
-        char *endptr;
-
-        *dest = strtol(arg, &endptr, 0);
-
-        if (*endptr != '\0') {
-               log_err("Invalid option: %s\n", arg);
-                argp_usage(state);
+       if (STREQ(arg, "disabled")) {
+               options.bsm_arg = RTC_BSM_DISABLED;
+       } else if (STREQ(arg, "direct")) {
+               options.bsm_arg = RTC_BSM_DIRECT;
+       } else if (STREQ(arg, "level")) {
+               options.bsm_arg = RTC_BSM_LEVEL;
+       } else if (STREQ(arg, "standby")) {
+               options.bsm_arg = RTC_BSM_STANDBY;
+       } else {
+               log_fail("Unknown BSM value: %s\n", arg);
+               argp_usage(state);
        }
 }
 
@@ -107,7 +121,10 @@ parse_opt(int key, char *arg, struct argp_state *state)
        case 'b':
                options.bsm = true;
                if (arg)
-                       decode_int(arg, state, &options.bsm_arg);
+                       decode_bsm(arg, state);
+               break;
+       case 'c':
+               options.clear = true;
                break;
        case 'd':
                options.rtc_path = arg;
@@ -123,6 +140,9 @@ parse_opt(int key, char *arg, struct argp_state *state)
        case 't':
                options.test = true;
                break;
+       case 'v':
+               options.vl_backup = true;
+               break;
        default:
                return ARGP_ERR_UNKNOWN;
        }
index 44c967b8d0fd9e64b6db658c9f5421af86db8cd6..c643ee57be6c3e666f1bb079ac5616a9aaeaa76d 100644 (file)
@@ -19,6 +19,8 @@ struct options_t {
        char *rtc_path;
        int bsm;
        int bsm_arg;
+       int vl_backup;
+       int clear;
        int test;
 };