linux/drivers/rtc/rtc-wm8350.c
<<
>>
Prefs
   1/*
   2 *      Real Time Clock driver for Wolfson Microelectronics WM8350
   3 *
   4 *      Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
   5 *
   6 *  Author: Liam Girdwood
   7 *          linux@wolfsonmicro.com
   8 *
   9 *  This program is free software; you can redistribute  it and/or modify it
  10 *  under  the terms of  the GNU General  Public License as published by the
  11 *  Free Software Foundation;  either version 2 of the  License, or (at your
  12 *  option) any later version.
  13 *
  14 */
  15
  16#include <linux/module.h>
  17#include <linux/kernel.h>
  18#include <linux/time.h>
  19#include <linux/rtc.h>
  20#include <linux/bcd.h>
  21#include <linux/interrupt.h>
  22#include <linux/ioctl.h>
  23#include <linux/completion.h>
  24#include <linux/mfd/wm8350/rtc.h>
  25#include <linux/mfd/wm8350/core.h>
  26#include <linux/delay.h>
  27#include <linux/platform_device.h>
  28
  29#define WM8350_SET_ALM_RETRIES  5
  30#define WM8350_SET_TIME_RETRIES 5
  31#define WM8350_GET_TIME_RETRIES 5
  32
  33/*
  34 * Read current time and date in RTC
  35 */
  36static int wm8350_rtc_readtime(struct device *dev, struct rtc_time *tm)
  37{
  38        struct wm8350 *wm8350 = dev_get_drvdata(dev);
  39        u16 time1[4], time2[4];
  40        int retries = WM8350_GET_TIME_RETRIES, ret;
  41
  42        /*
  43         * Read the time twice and compare.
  44         * If time1 == time2, then time is valid else retry.
  45         */
  46        do {
  47                ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES,
  48                                        4, time1);
  49                if (ret < 0)
  50                        return ret;
  51                ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES,
  52                                        4, time2);
  53                if (ret < 0)
  54                        return ret;
  55
  56                if (memcmp(time1, time2, sizeof(time1)) == 0) {
  57                        tm->tm_sec = time1[0] & WM8350_RTC_SECS_MASK;
  58
  59                        tm->tm_min = (time1[0] & WM8350_RTC_MINS_MASK)
  60                            >> WM8350_RTC_MINS_SHIFT;
  61
  62                        tm->tm_hour = time1[1] & WM8350_RTC_HRS_MASK;
  63
  64                        tm->tm_wday = ((time1[1] >> WM8350_RTC_DAY_SHIFT)
  65                                       & 0x7) - 1;
  66
  67                        tm->tm_mon = ((time1[2] & WM8350_RTC_MTH_MASK)
  68                                      >> WM8350_RTC_MTH_SHIFT) - 1;
  69
  70                        tm->tm_mday = (time1[2] & WM8350_RTC_DATE_MASK);
  71
  72                        tm->tm_year = ((time1[3] & WM8350_RTC_YHUNDREDS_MASK)
  73                                       >> WM8350_RTC_YHUNDREDS_SHIFT) * 100;
  74                        tm->tm_year += time1[3] & WM8350_RTC_YUNITS_MASK;
  75
  76                        tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon,
  77                                                    tm->tm_year);
  78                        tm->tm_year -= 1900;
  79
  80                        dev_dbg(dev, "Read (%d left): %04x %04x %04x %04x\n",
  81                                retries,
  82                                time1[0], time1[1], time1[2], time1[3]);
  83
  84                        return 0;
  85                }
  86        } while (retries--);
  87
  88        dev_err(dev, "timed out reading RTC time\n");
  89        return -EIO;
  90}
  91
  92/*
  93 * Set current time and date in RTC
  94 */
  95static int wm8350_rtc_settime(struct device *dev, struct rtc_time *tm)
  96{
  97        struct wm8350 *wm8350 = dev_get_drvdata(dev);
  98        u16 time[4];
  99        u16 rtc_ctrl;
 100        int ret, retries = WM8350_SET_TIME_RETRIES;
 101
 102        time[0] = tm->tm_sec;
 103        time[0] |= tm->tm_min << WM8350_RTC_MINS_SHIFT;
 104        time[1] = tm->tm_hour;
 105        time[1] |= (tm->tm_wday + 1) << WM8350_RTC_DAY_SHIFT;
 106        time[2] = tm->tm_mday;
 107        time[2] |= (tm->tm_mon + 1) << WM8350_RTC_MTH_SHIFT;
 108        time[3] = ((tm->tm_year + 1900) / 100) << WM8350_RTC_YHUNDREDS_SHIFT;
 109        time[3] |= (tm->tm_year + 1900) % 100;
 110
 111        dev_dbg(dev, "Setting: %04x %04x %04x %04x\n",
 112                time[0], time[1], time[2], time[3]);
 113
 114        /* Set RTC_SET to stop the clock */
 115        ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL, WM8350_RTC_SET);
 116        if (ret < 0)
 117                return ret;
 118
 119        /* Wait until confirmation of stopping */
 120        do {
 121                rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
 122                schedule_timeout_uninterruptible(msecs_to_jiffies(1));
 123        } while (--retries && !(rtc_ctrl & WM8350_RTC_STS));
 124
 125        if (!retries) {
 126                dev_err(dev, "timed out on set confirmation\n");
 127                return -EIO;
 128        }
 129
 130        /* Write time to RTC */
 131        ret = wm8350_block_write(wm8350, WM8350_RTC_SECONDS_MINUTES, 4, time);
 132        if (ret < 0)
 133                return ret;
 134
 135        /* Clear RTC_SET to start the clock */
 136        ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL,
 137                                WM8350_RTC_SET);
 138        return ret;
 139}
 140
 141/*
 142 * Read alarm time and date in RTC
 143 */
 144static int wm8350_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
 145{
 146        struct wm8350 *wm8350 = dev_get_drvdata(dev);
 147        struct rtc_time *tm = &alrm->time;
 148        u16 time[4];
 149        int ret;
 150
 151        ret = wm8350_block_read(wm8350, WM8350_ALARM_SECONDS_MINUTES, 4, time);
 152        if (ret < 0)
 153                return ret;
 154
 155        tm->tm_sec = time[0] & WM8350_RTC_ALMSECS_MASK;
 156        if (tm->tm_sec == WM8350_RTC_ALMSECS_MASK)
 157                tm->tm_sec = -1;
 158
 159        tm->tm_min = time[0] & WM8350_RTC_ALMMINS_MASK;
 160        if (tm->tm_min == WM8350_RTC_ALMMINS_MASK)
 161                tm->tm_min = -1;
 162        else
 163                tm->tm_min >>= WM8350_RTC_ALMMINS_SHIFT;
 164
 165        tm->tm_hour = time[1] & WM8350_RTC_ALMHRS_MASK;
 166        if (tm->tm_hour == WM8350_RTC_ALMHRS_MASK)
 167                tm->tm_hour = -1;
 168
 169        tm->tm_wday = ((time[1] >> WM8350_RTC_ALMDAY_SHIFT) & 0x7) - 1;
 170        if (tm->tm_wday > 7)
 171                tm->tm_wday = -1;
 172
 173        tm->tm_mon = time[2] & WM8350_RTC_ALMMTH_MASK;
 174        if (tm->tm_mon == WM8350_RTC_ALMMTH_MASK)
 175                tm->tm_mon = -1;
 176        else
 177                tm->tm_mon = (tm->tm_mon >> WM8350_RTC_ALMMTH_SHIFT) - 1;
 178
 179        tm->tm_mday = (time[2] & WM8350_RTC_ALMDATE_MASK);
 180        if (tm->tm_mday == WM8350_RTC_ALMDATE_MASK)
 181                tm->tm_mday = -1;
 182
 183        tm->tm_year = -1;
 184
 185        alrm->enabled = !(time[3] & WM8350_RTC_ALMSTS);
 186
 187        return 0;
 188}
 189
 190static int wm8350_rtc_stop_alarm(struct wm8350 *wm8350)
 191{
 192        int retries = WM8350_SET_ALM_RETRIES;
 193        u16 rtc_ctrl;
 194        int ret;
 195
 196        /* Set RTC_SET to stop the clock */
 197        ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL,
 198                              WM8350_RTC_ALMSET);
 199        if (ret < 0)
 200                return ret;
 201
 202        /* Wait until confirmation of stopping */
 203        do {
 204                rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
 205                schedule_timeout_uninterruptible(msecs_to_jiffies(1));
 206        } while (retries-- && !(rtc_ctrl & WM8350_RTC_ALMSTS));
 207
 208        if (!(rtc_ctrl & WM8350_RTC_ALMSTS))
 209                return -ETIMEDOUT;
 210
 211        return 0;
 212}
 213
 214static int wm8350_rtc_start_alarm(struct wm8350 *wm8350)
 215{
 216        int ret;
 217        int retries = WM8350_SET_ALM_RETRIES;
 218        u16 rtc_ctrl;
 219
 220        ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL,
 221                                WM8350_RTC_ALMSET);
 222        if (ret < 0)
 223                return ret;
 224
 225        /* Wait until confirmation */
 226        do {
 227                rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
 228                schedule_timeout_uninterruptible(msecs_to_jiffies(1));
 229        } while (retries-- && rtc_ctrl & WM8350_RTC_ALMSTS);
 230
 231        if (rtc_ctrl & WM8350_RTC_ALMSTS)
 232                return -ETIMEDOUT;
 233
 234        return 0;
 235}
 236
 237static int wm8350_rtc_alarm_irq_enable(struct device *dev,
 238                                       unsigned int enabled)
 239{
 240        struct wm8350 *wm8350 = dev_get_drvdata(dev);
 241
 242        if (enabled)
 243                return wm8350_rtc_start_alarm(wm8350);
 244        else
 245                return wm8350_rtc_stop_alarm(wm8350);
 246}
 247
 248static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
 249{
 250        struct wm8350 *wm8350 = dev_get_drvdata(dev);
 251        struct rtc_time *tm = &alrm->time;
 252        u16 time[3];
 253        int ret;
 254
 255        memset(time, 0, sizeof(time));
 256
 257        if (tm->tm_sec != -1)
 258                time[0] |= tm->tm_sec;
 259        else
 260                time[0] |= WM8350_RTC_ALMSECS_MASK;
 261
 262        if (tm->tm_min != -1)
 263                time[0] |= tm->tm_min << WM8350_RTC_ALMMINS_SHIFT;
 264        else
 265                time[0] |= WM8350_RTC_ALMMINS_MASK;
 266
 267        if (tm->tm_hour != -1)
 268                time[1] |= tm->tm_hour;
 269        else
 270                time[1] |= WM8350_RTC_ALMHRS_MASK;
 271
 272        if (tm->tm_wday != -1)
 273                time[1] |= (tm->tm_wday + 1) << WM8350_RTC_ALMDAY_SHIFT;
 274        else
 275                time[1] |= WM8350_RTC_ALMDAY_MASK;
 276
 277        if (tm->tm_mday != -1)
 278                time[2] |= tm->tm_mday;
 279        else
 280                time[2] |= WM8350_RTC_ALMDATE_MASK;
 281
 282        if (tm->tm_mon != -1)
 283                time[2] |= (tm->tm_mon + 1) << WM8350_RTC_ALMMTH_SHIFT;
 284        else
 285                time[2] |= WM8350_RTC_ALMMTH_MASK;
 286
 287        ret = wm8350_rtc_stop_alarm(wm8350);
 288        if (ret < 0)
 289                return ret;
 290
 291        /* Write time to RTC */
 292        ret = wm8350_block_write(wm8350, WM8350_ALARM_SECONDS_MINUTES,
 293                                 3, time);
 294        if (ret < 0)
 295                return ret;
 296
 297        if (alrm->enabled)
 298                ret = wm8350_rtc_start_alarm(wm8350);
 299
 300        return ret;
 301}
 302
 303static irqreturn_t wm8350_rtc_alarm_handler(int irq, void *data)
 304{
 305        struct wm8350 *wm8350 = data;
 306        struct rtc_device *rtc = wm8350->rtc.rtc;
 307        int ret;
 308
 309        rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF);
 310
 311        /* Make it one shot */
 312        ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL,
 313                              WM8350_RTC_ALMSET);
 314        if (ret != 0) {
 315                dev_err(&(wm8350->rtc.pdev->dev),
 316                        "Failed to disable alarm: %d\n", ret);
 317        }
 318
 319        return IRQ_HANDLED;
 320}
 321
 322static irqreturn_t wm8350_rtc_update_handler(int irq, void *data)
 323{
 324        struct wm8350 *wm8350 = data;
 325        struct rtc_device *rtc = wm8350->rtc.rtc;
 326
 327        rtc_update_irq(rtc, 1, RTC_IRQF | RTC_UF);
 328
 329        return IRQ_HANDLED;
 330}
 331
 332static const struct rtc_class_ops wm8350_rtc_ops = {
 333        .read_time = wm8350_rtc_readtime,
 334        .set_time = wm8350_rtc_settime,
 335        .read_alarm = wm8350_rtc_readalarm,
 336        .set_alarm = wm8350_rtc_setalarm,
 337        .alarm_irq_enable = wm8350_rtc_alarm_irq_enable,
 338};
 339
 340#ifdef CONFIG_PM_SLEEP
 341static int wm8350_rtc_suspend(struct device *dev)
 342{
 343        struct platform_device *pdev = to_platform_device(dev);
 344        struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev);
 345        int ret = 0;
 346        u16 reg;
 347
 348        reg = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
 349
 350        if (device_may_wakeup(&wm8350->rtc.pdev->dev) &&
 351            reg & WM8350_RTC_ALMSTS) {
 352                ret = wm8350_rtc_stop_alarm(wm8350);
 353                if (ret != 0)
 354                        dev_err(&pdev->dev, "Failed to stop RTC alarm: %d\n",
 355                                ret);
 356        }
 357
 358        return ret;
 359}
 360
 361static int wm8350_rtc_resume(struct device *dev)
 362{
 363        struct platform_device *pdev = to_platform_device(dev);
 364        struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev);
 365        int ret;
 366
 367        if (wm8350->rtc.alarm_enabled) {
 368                ret = wm8350_rtc_start_alarm(wm8350);
 369                if (ret != 0)
 370                        dev_err(&pdev->dev,
 371                                "Failed to restart RTC alarm: %d\n", ret);
 372        }
 373
 374        return 0;
 375}
 376#endif
 377
 378static int wm8350_rtc_probe(struct platform_device *pdev)
 379{
 380        struct wm8350 *wm8350 = platform_get_drvdata(pdev);
 381        struct wm8350_rtc *wm_rtc = &wm8350->rtc;
 382        int ret = 0;
 383        u16 timectl, power5;
 384
 385        timectl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
 386        if (timectl & WM8350_RTC_BCD) {
 387                dev_err(&pdev->dev, "RTC BCD mode not supported\n");
 388                return -EINVAL;
 389        }
 390        if (timectl & WM8350_RTC_12HR) {
 391                dev_err(&pdev->dev, "RTC 12 hour mode not supported\n");
 392                return -EINVAL;
 393        }
 394
 395        /* enable the RTC if it's not already enabled */
 396        power5 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_5);
 397        if (!(power5 &  WM8350_RTC_TICK_ENA)) {
 398                dev_info(wm8350->dev, "Starting RTC\n");
 399
 400                wm8350_reg_unlock(wm8350);
 401
 402                ret = wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5,
 403                                      WM8350_RTC_TICK_ENA);
 404                if (ret < 0) {
 405                        dev_err(&pdev->dev, "failed to enable RTC: %d\n", ret);
 406                        return ret;
 407                }
 408
 409                wm8350_reg_lock(wm8350);
 410        }
 411
 412        if (timectl & WM8350_RTC_STS) {
 413                int retries;
 414
 415                ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL,
 416                                        WM8350_RTC_SET);
 417                if (ret < 0) {
 418                        dev_err(&pdev->dev, "failed to start: %d\n", ret);
 419                        return ret;
 420                }
 421
 422                retries = WM8350_SET_TIME_RETRIES;
 423                do {
 424                        timectl = wm8350_reg_read(wm8350,
 425                                                  WM8350_RTC_TIME_CONTROL);
 426                } while (timectl & WM8350_RTC_STS && --retries);
 427
 428                if (retries == 0) {
 429                        dev_err(&pdev->dev, "failed to start: timeout\n");
 430                        return -ENODEV;
 431                }
 432        }
 433
 434        device_init_wakeup(&pdev->dev, 1);
 435
 436        wm_rtc->rtc = devm_rtc_device_register(&pdev->dev, "wm8350",
 437                                        &wm8350_rtc_ops, THIS_MODULE);
 438        if (IS_ERR(wm_rtc->rtc)) {
 439                ret = PTR_ERR(wm_rtc->rtc);
 440                dev_err(&pdev->dev, "failed to register RTC: %d\n", ret);
 441                return ret;
 442        }
 443
 444        wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC,
 445                            wm8350_rtc_update_handler, 0,
 446                            "RTC Seconds", wm8350);
 447        wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
 448
 449        wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM,
 450                            wm8350_rtc_alarm_handler, 0,
 451                            "RTC Alarm", wm8350);
 452
 453        return 0;
 454}
 455
 456static int wm8350_rtc_remove(struct platform_device *pdev)
 457{
 458        struct wm8350 *wm8350 = platform_get_drvdata(pdev);
 459
 460        wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350);
 461        wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM, wm8350);
 462
 463        return 0;
 464}
 465
 466static SIMPLE_DEV_PM_OPS(wm8350_rtc_pm_ops, wm8350_rtc_suspend,
 467                        wm8350_rtc_resume);
 468
 469static struct platform_driver wm8350_rtc_driver = {
 470        .probe = wm8350_rtc_probe,
 471        .remove = wm8350_rtc_remove,
 472        .driver = {
 473                .name = "wm8350-rtc",
 474                .pm = &wm8350_rtc_pm_ops,
 475        },
 476};
 477
 478module_platform_driver(wm8350_rtc_driver);
 479
 480MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 481MODULE_DESCRIPTION("RTC driver for the WM8350");
 482MODULE_LICENSE("GPL");
 483MODULE_ALIAS("platform:wm8350-rtc");
 484