linux/drivers/rtc/rtc-mc13xxx.c
<<
>>
Prefs
   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");
 366