History

rtc: pcf2127: add BSM support

The pcf2127 encodes BSM, BLD and power fail detection in the same set of bits so it is necessary to do some calculation when changing BSM to keep the rest of the configuration as-is. However, when BSM is disabled, there is no configuration with BLD enabled so this will be lost when coming back to a mode with BSM enabled.

Alexandre Belloni committed 1 year ago

Commit 97274521 parent 58589c61 file · +82 −0Browse files

Unified · Split

drivers/rtc/rtc-pcf2127.c+82−0
@@ -20,6 +20,7 @@ · 19 unmodified lines
2020 #include <linux/i2c.h>
2121 #include <linux/spi/spi.h>
2222 #include <linux/bcd.h>
23+#include <linux/bitfield.h>
2324 #include <linux/rtc.h>
2425 #include <linux/slab.h>
2526 #include <linux/module.h>
@@ -48,6 +49,7 @@ · 22 unmodified lines
4849 #define PCF2127_BIT_CTRL3_BLF BIT(2)
4950 #define PCF2127_BIT_CTRL3_BF BIT(3)
5051 #define PCF2127_BIT_CTRL3_BTSE BIT(4)
52+#define PCF2127_CTRL3_PM GENMASK(7, 5)
5153 /* Time and date registers */
5254 #define PCF2127_REG_TIME_BASE 0x03
5355 #define PCF2127_BIT_SC_OSF BIT(7)
@@ -331,6 +333,84 @@ static int pcf2127_rtc_set_time(struct device *dev, struct rtc_time *tm) · 277 unmodified lines
331333 return 0;
332334 }
333335
336+static int pcf2127_param_get(struct device *dev, struct rtc_param *param)
337+{
338+ struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
339+ u32 value;
340+ int ret;
341+
342+ switch (param->param) {
343+ case RTC_PARAM_BACKUP_SWITCH_MODE:
344+ ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL3, &value);
345+ if (ret < 0)
346+ return ret;
347+
348+ value = FIELD_GET(PCF2127_CTRL3_PM, value);
349+
350+ if (value < 0x3)
351+ param->uvalue = RTC_BSM_LEVEL;
352+ else if (value < 0x6)
353+ param->uvalue = RTC_BSM_DIRECT;
354+ else
355+ param->uvalue = RTC_BSM_DISABLED;
356+
357+ break;
358+
359+ default:
360+ return -EINVAL;
361+ }
362+
363+ return 0;
364+}
365+
366+static int pcf2127_param_set(struct device *dev, struct rtc_param *param)
367+{
368+ struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
369+ u8 mode = 0;
370+ u32 value;
371+ int ret;
372+
373+ switch (param->param) {
374+ case RTC_PARAM_BACKUP_SWITCH_MODE:
375+ ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL3, &value);
376+ if (ret < 0)
377+ return ret;
378+
379+ value = FIELD_GET(PCF2127_CTRL3_PM, value);
380+
381+ if (value > 5)
382+ value -= 5;
383+ else if (value > 2)
384+ value -= 3;
385+
386+ switch (param->uvalue) {
387+ case RTC_BSM_LEVEL:
388+ break;
389+ case RTC_BSM_DIRECT:
390+ mode = 3;
391+ break;
392+ case RTC_BSM_DISABLED:
393+ if (value == 0)
394+ value = 1;
395+ mode = 5;
396+ break;
397+ default:
398+ return -EINVAL;
399+ }
400+
401+ return regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL3,
402+ PCF2127_CTRL3_PM,
403+ FIELD_PREP(PCF2127_CTRL3_PM, mode + value));
404+
405+ break;
406+
407+ default:
408+ return -EINVAL;
409+ }
410+
411+ return 0;
412+}
413+
334414 static int pcf2127_rtc_ioctl(struct device *dev,
335415 unsigned int cmd, unsigned long arg)
336416 {
@@ -741,6 +821,8 @@ static const struct rtc_class_ops pcf2127_rtc_ops = { · 404 unmodified lines
741821 .read_alarm = pcf2127_rtc_read_alarm,
742822 .set_alarm = pcf2127_rtc_set_alarm,
743823 .alarm_irq_enable = pcf2127_rtc_alarm_irq_enable,
824+ .param_get = pcf2127_param_get,
825+ .param_set = pcf2127_param_set,
744826 };
745827
746828 /* sysfs interface */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t