1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Driver for the RTC found in the SpacemiT P1 PMIC 4 * 5 * Copyright (C) 2025 by RISCstar Solutions Corporation. All rights reserved. 6 */ 7 8 #include <linux/bits.h> 9 #include <linux/device.h> 10 #include <linux/module.h> 11 #include <linux/platform_device.h> 12 #include <linux/regmap.h> 13 #include <linux/rtc.h> 14 15 #define MOD_NAME "spacemit-p1-rtc" 16 17 /* 18 * Six consecutive 1-byte registers hold the seconds, minutes, hours, 19 * day-of-month, month, and year (respectively). 20 * 21 * The range of values in these registers is: 22 * seconds 0-59 23 * minutes 0-59 24 * hours 0-59 25 * day 0-30 (struct tm is 1-31) 26 * month 0-11 27 * year years since 2000 (struct tm is since 1900) 28 * 29 * Note that the day and month must be converted after reading and 30 * before writing. 31 */ 32 #define RTC_TIME 0x0d /* Offset of the seconds register */ 33 34 #define RTC_CTRL 0x1d 35 #define RTC_EN BIT(2) 36 37 /* Number of attempts to read a consistent time stamp before giving up */ 38 #define RTC_READ_TRIES 20 /* At least 1 */ 39 40 struct p1_rtc { 41 struct regmap *regmap; 42 struct rtc_device *rtc; 43 }; 44 45 /* 46 * The P1 hardware documentation states that the register values are 47 * latched to ensure a consistent time snapshot within the registers, 48 * but these are in fact unstable due to a bug in the hardware design. 49 * So we loop until we get two identical readings. 50 */ 51 static int p1_rtc_read_time(struct device *dev, struct rtc_time *t) 52 { 53 struct p1_rtc *p1 = dev_get_drvdata(dev); 54 struct regmap *regmap = p1->regmap; 55 u32 count = RTC_READ_TRIES; 56 u8 seconds; 57 u8 time[6]; 58 int ret; 59 60 ret = regmap_test_bits(regmap, RTC_CTRL, RTC_EN); 61 if (ret <= 0) 62 return ret ?: -EINVAL; /* RTC is disabled or error */ 63 64 ret = regmap_bulk_read(regmap, RTC_TIME, time, sizeof(time)); 65 if (ret) 66 return ret; 67 68 do { 69 seconds = time[0]; 70 ret = regmap_bulk_read(regmap, RTC_TIME, time, sizeof(time)); 71 if (ret) 72 return ret; 73 } while (time[0] != seconds && --count); 74 75 if (!count) 76 return -EIO; /* Unable to get a consistent result */ 77 78 t->tm_sec = time[0] & GENMASK(5, 0); 79 t->tm_min = time[1] & GENMASK(5, 0); 80 t->tm_hour = time[2] & GENMASK(4, 0); 81 t->tm_mday = (time[3] & GENMASK(4, 0)) + 1; 82 t->tm_mon = time[4] & GENMASK(3, 0); 83 t->tm_year = (time[5] & GENMASK(5, 0)) + 100; 84 85 return 0; 86 } 87 88 /* 89 * The P1 hardware documentation states that values in the registers are 90 * latched so when written they represent a consistent time snapshot. 91 * Nevertheless, this is not guaranteed by the implementation, so we must 92 * disable the RTC while updating it. 93 */ 94 static int p1_rtc_set_time(struct device *dev, struct rtc_time *t) 95 { 96 struct p1_rtc *p1 = dev_get_drvdata(dev); 97 struct regmap *regmap = p1->regmap; 98 u8 time[6]; 99 int ret; 100 101 time[0] = t->tm_sec; 102 time[1] = t->tm_min; 103 time[2] = t->tm_hour; 104 time[3] = t->tm_mday - 1; 105 time[4] = t->tm_mon; 106 time[5] = t->tm_year - 100; 107 108 /* Disable the RTC to update; re-enable again when done */ 109 ret = regmap_clear_bits(regmap, RTC_CTRL, RTC_EN); 110 if (ret) 111 return ret; 112 113 /* If something goes wrong, leave the RTC disabled */ 114 ret = regmap_bulk_write(regmap, RTC_TIME, time, sizeof(time)); 115 if (ret) 116 return ret; 117 118 return regmap_set_bits(regmap, RTC_CTRL, RTC_EN); 119 } 120 121 static const struct rtc_class_ops p1_rtc_class_ops = { 122 .read_time = p1_rtc_read_time, 123 .set_time = p1_rtc_set_time, 124 }; 125 126 static int p1_rtc_probe(struct platform_device *pdev) 127 { 128 struct device *dev = &pdev->dev; 129 struct rtc_device *rtc; 130 struct p1_rtc *p1; 131 132 p1 = devm_kzalloc(dev, sizeof(*p1), GFP_KERNEL); 133 if (!p1) 134 return -ENOMEM; 135 dev_set_drvdata(dev, p1); 136 137 p1->regmap = dev_get_regmap(dev->parent, NULL); 138 if (!p1->regmap) 139 return dev_err_probe(dev, -ENODEV, "failed to get regmap\n"); 140 141 rtc = devm_rtc_allocate_device(dev); 142 if (IS_ERR(rtc)) 143 return dev_err_probe(dev, PTR_ERR(rtc), 144 "error allocating device\n"); 145 p1->rtc = rtc; 146 147 rtc->ops = &p1_rtc_class_ops; 148 rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 149 rtc->range_max = RTC_TIMESTAMP_END_2063; 150 151 clear_bit(RTC_FEATURE_ALARM, rtc->features); 152 clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features); 153 154 return devm_rtc_register_device(rtc); 155 } 156 157 static struct platform_driver p1_rtc_driver = { 158 .probe = p1_rtc_probe, 159 .driver = { 160 .name = MOD_NAME, 161 }, 162 }; 163 164 module_platform_driver(p1_rtc_driver); 165 166 MODULE_DESCRIPTION("SpacemiT P1 RTC driver"); 167 MODULE_LICENSE("GPL"); 168 MODULE_ALIAS("platform:" MOD_NAME); 169