Commit 0d20e9fb authored by Alexandre Belloni's avatar Alexandre Belloni

rtc: add BSM parameter

BSM or Backup Switch Mode is a common feature on RTCs, allowing to select
how the RTC will decide when to switch from its primary power supply to the
backup power supply. It is necessary to be able to set it from userspace as
there are uses cases where it has to be done dynamically.

Supported values are:
  RTC_BSM_DISABLED: disabled
  RTC_BSM_DIRECT: switching will happen as soon as Vbackup > Vdd
  RTC_BSM_LEVEL: switching will happen around a threshold, usually with an
  hysteresis
  RTC_BSM_STANDBY: switching will not happen until Vdd > Vbackup, this is
  useful to ensure the RTC doesn't draw any power until the device is first
  powered on.
Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://lore.kernel.org/r/20211018151933.76865-6-alexandre.belloni@bootlin.com
parent a6d8c6e1
...@@ -409,7 +409,10 @@ static long rtc_dev_ioctl(struct file *file, ...@@ -409,7 +409,10 @@ static long rtc_dev_ioctl(struct file *file,
break; break;
default: default:
err = -EINVAL; if (rtc->ops->param_get)
err = rtc->ops->param_get(rtc->dev.parent, &param);
else
err = -EINVAL;
} }
if (!err) if (!err)
...@@ -436,7 +439,10 @@ static long rtc_dev_ioctl(struct file *file, ...@@ -436,7 +439,10 @@ static long rtc_dev_ioctl(struct file *file,
return rtc_set_offset(rtc, param.svalue); return rtc_set_offset(rtc, param.svalue);
default: default:
err = -EINVAL; if (rtc->ops->param_set)
err = rtc->ops->param_set(rtc->dev.parent, &param);
else
err = -EINVAL;
} }
break; break;
......
...@@ -66,6 +66,8 @@ struct rtc_class_ops { ...@@ -66,6 +66,8 @@ struct rtc_class_ops {
int (*alarm_irq_enable)(struct device *, unsigned int enabled); int (*alarm_irq_enable)(struct device *, unsigned int enabled);
int (*read_offset)(struct device *, long *offset); int (*read_offset)(struct device *, long *offset);
int (*set_offset)(struct device *, long offset); int (*set_offset)(struct device *, long offset);
int (*param_get)(struct device *, struct rtc_param *param);
int (*param_set)(struct device *, struct rtc_param *param);
}; };
struct rtc_device; struct rtc_device;
......
...@@ -132,11 +132,18 @@ struct rtc_param { ...@@ -132,11 +132,18 @@ struct rtc_param {
#define RTC_FEATURE_ALARM_RES_2S 3 #define RTC_FEATURE_ALARM_RES_2S 3
#define RTC_FEATURE_UPDATE_INTERRUPT 4 #define RTC_FEATURE_UPDATE_INTERRUPT 4
#define RTC_FEATURE_CORRECTION 5 #define RTC_FEATURE_CORRECTION 5
#define RTC_FEATURE_CNT 6 #define RTC_FEATURE_BACKUP_SWITCH_MODE 6
#define RTC_FEATURE_CNT 7
/* parameter list */ /* parameter list */
#define RTC_PARAM_FEATURES 0 #define RTC_PARAM_FEATURES 0
#define RTC_PARAM_CORRECTION 1 #define RTC_PARAM_CORRECTION 1
#define RTC_PARAM_BACKUP_SWITCH_MODE 2
#define RTC_BSM_DISABLED 0
#define RTC_BSM_DIRECT 1
#define RTC_BSM_LEVEL 2
#define RTC_BSM_STANDBY 3
#define RTC_MAX_FREQ 8192 #define RTC_MAX_FREQ 8192
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment