#include <linux/i2c.h>
 #include <linux/spi/spi.h>
 #include <linux/bcd.h>
+#include <linux/bitfield.h>
 #include <linux/rtc.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #define PCF2127_BIT_CTRL3_BLF                  BIT(2)
 #define PCF2127_BIT_CTRL3_BF                   BIT(3)
 #define PCF2127_BIT_CTRL3_BTSE                 BIT(4)
+#define PCF2127_CTRL3_PM                       GENMASK(7, 5)
 /* Time and date registers */
 #define PCF2127_REG_TIME_BASE          0x03
 #define PCF2127_BIT_SC_OSF                     BIT(7)
        return 0;
 }
 
+static int pcf2127_param_get(struct device *dev, struct rtc_param *param)
+{
+       struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
+       u32 value;
+       int ret;
+
+       switch (param->param) {
+       case RTC_PARAM_BACKUP_SWITCH_MODE:
+               ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL3, &value);
+               if (ret < 0)
+                       return ret;
+
+               value = FIELD_GET(PCF2127_CTRL3_PM, value);
+
+               if (value < 0x3)
+                       param->uvalue = RTC_BSM_LEVEL;
+               else if (value < 0x6)
+                       param->uvalue = RTC_BSM_DIRECT;
+               else
+                       param->uvalue = RTC_BSM_DISABLED;
+
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int pcf2127_param_set(struct device *dev, struct rtc_param *param)
+{
+       struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
+       u8 mode = 0;
+       u32 value;
+       int ret;
+
+       switch (param->param) {
+       case RTC_PARAM_BACKUP_SWITCH_MODE:
+               ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL3, &value);
+               if (ret < 0)
+                       return ret;
+
+               value = FIELD_GET(PCF2127_CTRL3_PM, value);
+
+               if (value > 5)
+                       value -= 5;
+               else if (value > 2)
+                       value -= 3;
+
+               switch (param->uvalue) {
+               case RTC_BSM_LEVEL:
+                       break;
+               case RTC_BSM_DIRECT:
+                       mode = 3;
+                       break;
+               case RTC_BSM_DISABLED:
+                       if (value == 0)
+                               value = 1;
+                       mode = 5;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               return regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL3,
+                                         PCF2127_CTRL3_PM,
+                                         FIELD_PREP(PCF2127_CTRL3_PM, mode + value));
+
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static int pcf2127_rtc_ioctl(struct device *dev,
                                unsigned int cmd, unsigned long arg)
 {
        .read_alarm       = pcf2127_rtc_read_alarm,
        .set_alarm        = pcf2127_rtc_set_alarm,
        .alarm_irq_enable = pcf2127_rtc_alarm_irq_enable,
+       .param_get        = pcf2127_param_get,
+       .param_set        = pcf2127_param_set,
 };
 
 /* sysfs interface */