1 /* 2 * Real Time Clock driver for Freescale MC13XXX PMIC 3 * 4 * (C) 2009 Sascha Hauer, Pengutronix 5 * (C) 2009 Uwe Kleine-Koenig, Pengutronix 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 12 #include <linux/mfd/mc13xxx.h> 13 #include <linux/platform_device.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/slab.h> 17 #include <linux/rtc.h> 18 19 #define DRIVER_NAME "mc13xxx-rtc" 20 21 #define MC13XXX_RTCTOD 20 22 #define MC13XXX_RTCTODA 21 23 #define MC13XXX_RTCDAY 22 24 #define MC13XXX_RTCDAYA 23 25 26 struct mc13xxx_rtc { 27 struct rtc_device *rtc; 28 struct mc13xxx *mc13xxx; 29 int valid; 30 }; 31 32 static 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 45 static int mc13xxx_rtc_irq_enable(struct device *dev, 46 unsigned int enabled, int irq) 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, irq); 54 55 mc13xxx_unlock(priv->mc13xxx); 56 57 return ret; 58 } 59 60 static 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 unsigned long s1970; 65 int ret; 66 67 mc13xxx_lock(priv->mc13xxx); 68 69 if (!priv->valid) { 70 ret = -ENODATA; 71 goto out; 72 } 73 74 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days1); 75 if (unlikely(ret)) 76 goto out; 77 78 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTOD, &seconds); 79 if (unlikely(ret)) 80 goto out; 81 82 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days2); 83 out: 84 mc13xxx_unlock(priv->mc13xxx); 85 86 if (ret) 87 return ret; 88 89 if (days2 == days1 + 1) { 90 if (seconds >= 86400 / 2) 91 days2 = days1; 92 else 93 days1 = days2; 94 } 95 96 if (days1 != days2) 97 return -EIO; 98 99 s1970 = days1 * 86400 + seconds; 100 101 rtc_time_to_tm(s1970, tm); 102 103 return rtc_valid_tm(tm); 104 } 105 106 static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs) 107 { 108 struct mc13xxx_rtc *priv = dev_get_drvdata(dev); 109 unsigned int seconds, days; 110 unsigned int alarmseconds; 111 int ret; 112 113 seconds = secs % 86400; 114 days = secs / 86400; 115 116 mc13xxx_lock(priv->mc13xxx); 117 118 /* 119 * temporarily invalidate alarm to prevent triggering it when the day is 120 * already updated while the time isn't yet. 121 */ 122 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &alarmseconds); 123 if (unlikely(ret)) 124 goto out; 125 126 if (alarmseconds < 86400) { 127 ret = mc13xxx_reg_write(priv->mc13xxx, 128 MC13XXX_RTCTODA, 0x1ffff); 129 if (unlikely(ret)) 130 goto out; 131 } 132 133 /* 134 * write seconds=0 to prevent a day switch between writing days 135 * and seconds below 136 */ 137 ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, 0); 138 if (unlikely(ret)) 139 goto out; 140 141 ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAY, days); 142 if (unlikely(ret)) 143 goto out; 144 145 ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, seconds); 146 if (unlikely(ret)) 147 goto out; 148 149 /* restore alarm */ 150 if (alarmseconds < 86400) { 151 ret = mc13xxx_reg_write(priv->mc13xxx, 152 MC13XXX_RTCTODA, alarmseconds); 153 if (unlikely(ret)) 154 goto out; 155 } 156 157 ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_RTCRST); 158 if (unlikely(ret)) 159 goto out; 160 161 ret = mc13xxx_irq_unmask(priv->mc13xxx, MC13XXX_IRQ_RTCRST); 162 out: 163 priv->valid = !ret; 164 165 mc13xxx_unlock(priv->mc13xxx); 166 167 return ret; 168 } 169 170 static int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) 171 { 172 struct mc13xxx_rtc *priv = dev_get_drvdata(dev); 173 unsigned seconds, days; 174 unsigned long s1970; 175 int enabled, pending; 176 int ret; 177 178 mc13xxx_lock(priv->mc13xxx); 179 180 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &seconds); 181 if (unlikely(ret)) 182 goto out; 183 if (seconds >= 86400) { 184 ret = -ENODATA; 185 goto out; 186 } 187 188 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days); 189 if (unlikely(ret)) 190 goto out; 191 192 ret = mc13xxx_irq_status(priv->mc13xxx, MC13XXX_IRQ_TODA, 193 &enabled, &pending); 194 195 out: 196 mc13xxx_unlock(priv->mc13xxx); 197 198 if (ret) 199 return ret; 200 201 alarm->enabled = enabled; 202 alarm->pending = pending; 203 204 s1970 = days * 86400 + seconds; 205 206 rtc_time_to_tm(s1970, &alarm->time); 207 dev_dbg(dev, "%s: %lu\n", __func__, s1970); 208 209 return 0; 210 } 211 212 static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) 213 { 214 struct mc13xxx_rtc *priv = dev_get_drvdata(dev); 215 unsigned long s1970; 216 unsigned seconds, days; 217 int ret; 218 219 mc13xxx_lock(priv->mc13xxx); 220 221 /* disable alarm to prevent false triggering */ 222 ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, 0x1ffff); 223 if (unlikely(ret)) 224 goto out; 225 226 ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_TODA); 227 if (unlikely(ret)) 228 goto out; 229 230 ret = rtc_tm_to_time(&alarm->time, &s1970); 231 if (unlikely(ret)) 232 goto out; 233 234 dev_dbg(dev, "%s: o%2.s %lu\n", __func__, alarm->enabled ? "n" : "ff", 235 s1970); 236 237 ret = mc13xxx_rtc_irq_enable_unlocked(dev, alarm->enabled, 238 MC13XXX_IRQ_TODA); 239 if (unlikely(ret)) 240 goto out; 241 242 seconds = s1970 % 86400; 243 days = s1970 / 86400; 244 245 ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAYA, days); 246 if (unlikely(ret)) 247 goto out; 248 249 ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, seconds); 250 251 out: 252 mc13xxx_unlock(priv->mc13xxx); 253 254 return ret; 255 } 256 257 static irqreturn_t mc13xxx_rtc_alarm_handler(int irq, void *dev) 258 { 259 struct mc13xxx_rtc *priv = dev; 260 struct mc13xxx *mc13xxx = priv->mc13xxx; 261 262 dev_dbg(&priv->rtc->dev, "Alarm\n"); 263 264 rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_AF); 265 266 mc13xxx_irq_ack(mc13xxx, irq); 267 268 return IRQ_HANDLED; 269 } 270 271 static irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev) 272 { 273 struct mc13xxx_rtc *priv = dev; 274 struct mc13xxx *mc13xxx = priv->mc13xxx; 275 276 dev_dbg(&priv->rtc->dev, "1HZ\n"); 277 278 rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF); 279 280 mc13xxx_irq_ack(mc13xxx, irq); 281 282 return IRQ_HANDLED; 283 } 284 285 static int mc13xxx_rtc_alarm_irq_enable(struct device *dev, 286 unsigned int enabled) 287 { 288 return mc13xxx_rtc_irq_enable(dev, enabled, MC13XXX_IRQ_TODA); 289 } 290 291 static const struct rtc_class_ops mc13xxx_rtc_ops = { 292 .read_time = mc13xxx_rtc_read_time, 293 .set_mmss = mc13xxx_rtc_set_mmss, 294 .read_alarm = mc13xxx_rtc_read_alarm, 295 .set_alarm = mc13xxx_rtc_set_alarm, 296 .alarm_irq_enable = mc13xxx_rtc_alarm_irq_enable, 297 }; 298 299 static irqreturn_t mc13xxx_rtc_reset_handler(int irq, void *dev) 300 { 301 struct mc13xxx_rtc *priv = dev; 302 struct mc13xxx *mc13xxx = priv->mc13xxx; 303 304 dev_dbg(&priv->rtc->dev, "RTCRST\n"); 305 priv->valid = 0; 306 307 mc13xxx_irq_mask(mc13xxx, irq); 308 309 return IRQ_HANDLED; 310 } 311 312 static int __init mc13xxx_rtc_probe(struct platform_device *pdev) 313 { 314 int ret; 315 struct mc13xxx_rtc *priv; 316 struct mc13xxx *mc13xxx; 317 int rtcrst_pending; 318 319 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 320 if (!priv) 321 return -ENOMEM; 322 323 mc13xxx = dev_get_drvdata(pdev->dev.parent); 324 priv->mc13xxx = mc13xxx; 325 326 platform_set_drvdata(pdev, priv); 327 328 mc13xxx_lock(mc13xxx); 329 330 ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_RTCRST, 331 mc13xxx_rtc_reset_handler, DRIVER_NAME, priv); 332 if (ret) 333 goto err_reset_irq_request; 334 335 ret = mc13xxx_irq_status(mc13xxx, MC13XXX_IRQ_RTCRST, 336 NULL, &rtcrst_pending); 337 if (ret) 338 goto err_reset_irq_status; 339 340 priv->valid = !rtcrst_pending; 341 342 ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_1HZ, 343 mc13xxx_rtc_update_handler, DRIVER_NAME, priv); 344 if (ret) 345 goto err_update_irq_request; 346 347 ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_TODA, 348 mc13xxx_rtc_alarm_handler, DRIVER_NAME, priv); 349 if (ret) 350 goto err_alarm_irq_request; 351 352 mc13xxx_unlock(mc13xxx); 353 354 priv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, 355 &mc13xxx_rtc_ops, THIS_MODULE); 356 if (IS_ERR(priv->rtc)) { 357 ret = PTR_ERR(priv->rtc); 358 359 mc13xxx_lock(mc13xxx); 360 361 mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_TODA, priv); 362 err_alarm_irq_request: 363 364 mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_1HZ, priv); 365 err_update_irq_request: 366 367 err_reset_irq_status: 368 369 mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv); 370 err_reset_irq_request: 371 372 mc13xxx_unlock(mc13xxx); 373 } 374 375 return ret; 376 } 377 378 static int __exit mc13xxx_rtc_remove(struct platform_device *pdev) 379 { 380 struct mc13xxx_rtc *priv = platform_get_drvdata(pdev); 381 382 mc13xxx_lock(priv->mc13xxx); 383 384 mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_TODA, priv); 385 mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_1HZ, priv); 386 mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_RTCRST, priv); 387 388 mc13xxx_unlock(priv->mc13xxx); 389 390 return 0; 391 } 392 393 static const struct platform_device_id mc13xxx_rtc_idtable[] = { 394 { 395 .name = "mc13783-rtc", 396 }, { 397 .name = "mc13892-rtc", 398 }, { 399 .name = "mc34708-rtc", 400 }, 401 { /* sentinel */ } 402 }; 403 MODULE_DEVICE_TABLE(platform, mc13xxx_rtc_idtable); 404 405 static struct platform_driver mc13xxx_rtc_driver = { 406 .id_table = mc13xxx_rtc_idtable, 407 .remove = __exit_p(mc13xxx_rtc_remove), 408 .driver = { 409 .name = DRIVER_NAME, 410 .owner = THIS_MODULE, 411 }, 412 }; 413 414 module_platform_driver_probe(mc13xxx_rtc_driver, &mc13xxx_rtc_probe); 415 416 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); 417 MODULE_DESCRIPTION("RTC driver for Freescale MC13XXX PMIC"); 418 MODULE_LICENSE("GPL v2"); 419