rtc-mc13xxx.c (8141B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Real Time Clock driver for Freescale MC13XXX PMIC 4 * 5 * (C) 2009 Sascha Hauer, Pengutronix 6 * (C) 2009 Uwe Kleine-Koenig, Pengutronix 7 */ 8 9#include <linux/mfd/mc13xxx.h> 10#include <linux/platform_device.h> 11#include <linux/kernel.h> 12#include <linux/module.h> 13#include <linux/mod_devicetable.h> 14#include <linux/slab.h> 15#include <linux/rtc.h> 16 17#define DRIVER_NAME "mc13xxx-rtc" 18 19#define MC13XXX_RTCTOD 20 20#define MC13XXX_RTCTODA 21 21#define MC13XXX_RTCDAY 22 22#define MC13XXX_RTCDAYA 23 23 24#define SEC_PER_DAY (24 * 60 * 60) 25 26struct mc13xxx_rtc { 27 struct rtc_device *rtc; 28 struct mc13xxx *mc13xxx; 29 int valid; 30}; 31 32static int mc13xxx_rtc_irq_enable_unlocked(struct device *dev, 33 unsigned int enabled, int irq) 34{ 35 struct mc13xxx_rtc *priv = dev_get_drvdata(dev); 36 int (*func)(struct mc13xxx *mc13xxx, int irq); 37 38 if (!priv->valid) 39 return -ENODATA; 40 41 func = enabled ? mc13xxx_irq_unmask : mc13xxx_irq_mask; 42 return func(priv->mc13xxx, irq); 43} 44 45static int mc13xxx_rtc_alarm_irq_enable(struct device *dev, 46 unsigned int enabled) 47{ 48 struct mc13xxx_rtc *priv = dev_get_drvdata(dev); 49 int ret; 50 51 mc13xxx_lock(priv->mc13xxx); 52 53 ret = mc13xxx_rtc_irq_enable_unlocked(dev, enabled, MC13XXX_IRQ_TODA); 54 55 mc13xxx_unlock(priv->mc13xxx); 56 57 return ret; 58} 59 60static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) 61{ 62 struct mc13xxx_rtc *priv = dev_get_drvdata(dev); 63 unsigned int seconds, days1, days2; 64 65 if (!priv->valid) 66 return -ENODATA; 67 68 do { 69 int ret; 70 71 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days1); 72 if (ret) 73 return ret; 74 75 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTOD, &seconds); 76 if (ret) 77 return ret; 78 79 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days2); 80 if (ret) 81 return ret; 82 } while (days1 != days2); 83 84 rtc_time64_to_tm((time64_t)days1 * SEC_PER_DAY + seconds, tm); 85 86 return 0; 87} 88 89static int mc13xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) 90{ 91 struct mc13xxx_rtc *priv = dev_get_drvdata(dev); 92 unsigned int seconds, days; 93 unsigned int alarmseconds; 94 int ret; 95 96 days = div_s64_rem(rtc_tm_to_time64(tm), SEC_PER_DAY, &seconds); 97 98 mc13xxx_lock(priv->mc13xxx); 99 100 /* 101 * temporarily invalidate alarm to prevent triggering it when the day is 102 * already updated while the time isn't yet. 103 */ 104 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &alarmseconds); 105 if (unlikely(ret)) 106 goto out; 107 108 if (alarmseconds < SEC_PER_DAY) { 109 ret = mc13xxx_reg_write(priv->mc13xxx, 110 MC13XXX_RTCTODA, 0x1ffff); 111 if (unlikely(ret)) 112 goto out; 113 } 114 115 /* 116 * write seconds=0 to prevent a day switch between writing days 117 * and seconds below 118 */ 119 ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, 0); 120 if (unlikely(ret)) 121 goto out; 122 123 ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAY, days); 124 if (unlikely(ret)) 125 goto out; 126 127 ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, seconds); 128 if (unlikely(ret)) 129 goto out; 130 131 /* restore alarm */ 132 if (alarmseconds < SEC_PER_DAY) { 133 ret = mc13xxx_reg_write(priv->mc13xxx, 134 MC13XXX_RTCTODA, alarmseconds); 135 if (unlikely(ret)) 136 goto out; 137 } 138 139 if (!priv->valid) { 140 ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_RTCRST); 141 if (unlikely(ret)) 142 goto out; 143 144 ret = mc13xxx_irq_unmask(priv->mc13xxx, MC13XXX_IRQ_RTCRST); 145 } 146 147out: 148 priv->valid = !ret; 149 150 mc13xxx_unlock(priv->mc13xxx); 151 152 return ret; 153} 154 155static int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) 156{ 157 struct mc13xxx_rtc *priv = dev_get_drvdata(dev); 158 unsigned int seconds, days; 159 time64_t s1970; 160 int enabled, pending; 161 int ret; 162 163 mc13xxx_lock(priv->mc13xxx); 164 165 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &seconds); 166 if (unlikely(ret)) 167 goto out; 168 if (seconds >= SEC_PER_DAY) { 169 ret = -ENODATA; 170 goto out; 171 } 172 173 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days); 174 if (unlikely(ret)) 175 goto out; 176 177 ret = mc13xxx_irq_status(priv->mc13xxx, MC13XXX_IRQ_TODA, 178 &enabled, &pending); 179 180out: 181 mc13xxx_unlock(priv->mc13xxx); 182 183 if (ret) 184 return ret; 185 186 alarm->enabled = enabled; 187 alarm->pending = pending; 188 189 s1970 = (time64_t)days * SEC_PER_DAY + seconds; 190 191 rtc_time64_to_tm(s1970, &alarm->time); 192 dev_dbg(dev, "%s: %lld\n", __func__, (long long)s1970); 193 194 return 0; 195} 196 197static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) 198{ 199 struct mc13xxx_rtc *priv = dev_get_drvdata(dev); 200 time64_t s1970; 201 u32 seconds, days; 202 int ret; 203 204 mc13xxx_lock(priv->mc13xxx); 205 206 /* disable alarm to prevent false triggering */ 207 ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, 0x1ffff); 208 if (unlikely(ret)) 209 goto out; 210 211 ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_TODA); 212 if (unlikely(ret)) 213 goto out; 214 215 s1970 = rtc_tm_to_time64(&alarm->time); 216 217 dev_dbg(dev, "%s: %s %lld\n", __func__, alarm->enabled ? "on" : "off", 218 (long long)s1970); 219 220 ret = mc13xxx_rtc_irq_enable_unlocked(dev, alarm->enabled, 221 MC13XXX_IRQ_TODA); 222 if (unlikely(ret)) 223 goto out; 224 225 days = div_s64_rem(s1970, SEC_PER_DAY, &seconds); 226 227 ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAYA, days); 228 if (unlikely(ret)) 229 goto out; 230 231 ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, seconds); 232 233out: 234 mc13xxx_unlock(priv->mc13xxx); 235 236 return ret; 237} 238 239static irqreturn_t mc13xxx_rtc_alarm_handler(int irq, void *dev) 240{ 241 struct mc13xxx_rtc *priv = dev; 242 struct mc13xxx *mc13xxx = priv->mc13xxx; 243 244 rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_AF); 245 246 mc13xxx_irq_ack(mc13xxx, irq); 247 248 return IRQ_HANDLED; 249} 250 251static const struct rtc_class_ops mc13xxx_rtc_ops = { 252 .read_time = mc13xxx_rtc_read_time, 253 .set_time = mc13xxx_rtc_set_time, 254 .read_alarm = mc13xxx_rtc_read_alarm, 255 .set_alarm = mc13xxx_rtc_set_alarm, 256 .alarm_irq_enable = mc13xxx_rtc_alarm_irq_enable, 257}; 258 259static irqreturn_t mc13xxx_rtc_reset_handler(int irq, void *dev) 260{ 261 struct mc13xxx_rtc *priv = dev; 262 struct mc13xxx *mc13xxx = priv->mc13xxx; 263 264 priv->valid = 0; 265 266 mc13xxx_irq_mask(mc13xxx, irq); 267 268 return IRQ_HANDLED; 269} 270 271static int __init mc13xxx_rtc_probe(struct platform_device *pdev) 272{ 273 int ret; 274 struct mc13xxx_rtc *priv; 275 struct mc13xxx *mc13xxx; 276 277 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 278 if (!priv) 279 return -ENOMEM; 280 281 mc13xxx = dev_get_drvdata(pdev->dev.parent); 282 priv->mc13xxx = mc13xxx; 283 priv->valid = 1; 284 285 priv->rtc = devm_rtc_allocate_device(&pdev->dev); 286 if (IS_ERR(priv->rtc)) 287 return PTR_ERR(priv->rtc); 288 platform_set_drvdata(pdev, priv); 289 290 priv->rtc->ops = &mc13xxx_rtc_ops; 291 /* 15bit days + hours, minutes, seconds */ 292 priv->rtc->range_max = (timeu64_t)(1 << 15) * SEC_PER_DAY - 1; 293 294 mc13xxx_lock(mc13xxx); 295 296 mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_RTCRST); 297 298 ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_RTCRST, 299 mc13xxx_rtc_reset_handler, DRIVER_NAME, priv); 300 if (ret) 301 goto err_irq_request; 302 303 ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_TODA, 304 mc13xxx_rtc_alarm_handler, DRIVER_NAME, priv); 305 if (ret) 306 goto err_irq_request; 307 308 mc13xxx_unlock(mc13xxx); 309 310 ret = devm_rtc_register_device(priv->rtc); 311 if (ret) { 312 mc13xxx_lock(mc13xxx); 313 goto err_irq_request; 314 } 315 316 return 0; 317 318err_irq_request: 319 mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_TODA, priv); 320 mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv); 321 322 mc13xxx_unlock(mc13xxx); 323 324 return ret; 325} 326 327static int mc13xxx_rtc_remove(struct platform_device *pdev) 328{ 329 struct mc13xxx_rtc *priv = platform_get_drvdata(pdev); 330 331 mc13xxx_lock(priv->mc13xxx); 332 333 mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_TODA, priv); 334 mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_RTCRST, priv); 335 336 mc13xxx_unlock(priv->mc13xxx); 337 338 return 0; 339} 340 341static const struct platform_device_id mc13xxx_rtc_idtable[] = { 342 { 343 .name = "mc13783-rtc", 344 }, { 345 .name = "mc13892-rtc", 346 }, { 347 .name = "mc34708-rtc", 348 }, 349 { /* sentinel */ } 350}; 351MODULE_DEVICE_TABLE(platform, mc13xxx_rtc_idtable); 352 353static struct platform_driver mc13xxx_rtc_driver = { 354 .id_table = mc13xxx_rtc_idtable, 355 .remove = mc13xxx_rtc_remove, 356 .driver = { 357 .name = DRIVER_NAME, 358 }, 359}; 360 361module_platform_driver_probe(mc13xxx_rtc_driver, &mc13xxx_rtc_probe); 362 363MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); 364MODULE_DESCRIPTION("RTC driver for Freescale MC13XXX PMIC"); 365MODULE_LICENSE("GPL v2");