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