linux/drivers/rtc/rtc-mxc.c
<<
>>
Prefs
   1/*
   2 * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
   3 *
   4 * The code contained herein is licensed under the GNU General Public
   5 * License. You may obtain a copy of the GNU General Public License
   6 * Version 2 or later at the following locations:
   7 *
   8 * http://www.opensource.org/licenses/gpl-license.html
   9 * http://www.gnu.org/copyleft/gpl.html
  10 */
  11
  12#include <linux/io.h>
  13#include <linux/rtc.h>
  14#include <linux/module.h>
  15#include <linux/slab.h>
  16#include <linux/interrupt.h>
  17#include <linux/platform_device.h>
  18#include <linux/clk.h>
  19
  20#include <mach/hardware.h>
  21
  22#define RTC_INPUT_CLK_32768HZ   (0x00 << 5)
  23#define RTC_INPUT_CLK_32000HZ   (0x01 << 5)
  24#define RTC_INPUT_CLK_38400HZ   (0x02 << 5)
  25
  26#define RTC_SW_BIT      (1 << 0)
  27#define RTC_ALM_BIT     (1 << 2)
  28#define RTC_1HZ_BIT     (1 << 4)
  29#define RTC_2HZ_BIT     (1 << 7)
  30#define RTC_SAM0_BIT    (1 << 8)
  31#define RTC_SAM1_BIT    (1 << 9)
  32#define RTC_SAM2_BIT    (1 << 10)
  33#define RTC_SAM3_BIT    (1 << 11)
  34#define RTC_SAM4_BIT    (1 << 12)
  35#define RTC_SAM5_BIT    (1 << 13)
  36#define RTC_SAM6_BIT    (1 << 14)
  37#define RTC_SAM7_BIT    (1 << 15)
  38#define PIT_ALL_ON      (RTC_2HZ_BIT | RTC_SAM0_BIT | RTC_SAM1_BIT | \
  39                         RTC_SAM2_BIT | RTC_SAM3_BIT | RTC_SAM4_BIT | \
  40                         RTC_SAM5_BIT | RTC_SAM6_BIT | RTC_SAM7_BIT)
  41
  42#define RTC_ENABLE_BIT  (1 << 7)
  43
  44#define MAX_PIE_NUM     9
  45#define MAX_PIE_FREQ    512
  46static const u32 PIE_BIT_DEF[MAX_PIE_NUM][2] = {
  47        { 2,            RTC_2HZ_BIT },
  48        { 4,            RTC_SAM0_BIT },
  49        { 8,            RTC_SAM1_BIT },
  50        { 16,           RTC_SAM2_BIT },
  51        { 32,           RTC_SAM3_BIT },
  52        { 64,           RTC_SAM4_BIT },
  53        { 128,          RTC_SAM5_BIT },
  54        { 256,          RTC_SAM6_BIT },
  55        { MAX_PIE_FREQ, RTC_SAM7_BIT },
  56};
  57
  58#define MXC_RTC_TIME    0
  59#define MXC_RTC_ALARM   1
  60
  61#define RTC_HOURMIN     0x00    /*  32bit rtc hour/min counter reg */
  62#define RTC_SECOND      0x04    /*  32bit rtc seconds counter reg */
  63#define RTC_ALRM_HM     0x08    /*  32bit rtc alarm hour/min reg */
  64#define RTC_ALRM_SEC    0x0C    /*  32bit rtc alarm seconds reg */
  65#define RTC_RTCCTL      0x10    /*  32bit rtc control reg */
  66#define RTC_RTCISR      0x14    /*  32bit rtc interrupt status reg */
  67#define RTC_RTCIENR     0x18    /*  32bit rtc interrupt enable reg */
  68#define RTC_STPWCH      0x1C    /*  32bit rtc stopwatch min reg */
  69#define RTC_DAYR        0x20    /*  32bit rtc days counter reg */
  70#define RTC_DAYALARM    0x24    /*  32bit rtc day alarm reg */
  71#define RTC_TEST1       0x28    /*  32bit rtc test reg 1 */
  72#define RTC_TEST2       0x2C    /*  32bit rtc test reg 2 */
  73#define RTC_TEST3       0x30    /*  32bit rtc test reg 3 */
  74
  75struct rtc_plat_data {
  76        struct rtc_device *rtc;
  77        void __iomem *ioaddr;
  78        int irq;
  79        struct clk *clk;
  80        struct rtc_time g_rtc_alarm;
  81};
  82
  83/*
  84 * This function is used to obtain the RTC time or the alarm value in
  85 * second.
  86 */
  87static u32 get_alarm_or_time(struct device *dev, int time_alarm)
  88{
  89        struct platform_device *pdev = to_platform_device(dev);
  90        struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
  91        void __iomem *ioaddr = pdata->ioaddr;
  92        u32 day = 0, hr = 0, min = 0, sec = 0, hr_min = 0;
  93
  94        switch (time_alarm) {
  95        case MXC_RTC_TIME:
  96                day = readw(ioaddr + RTC_DAYR);
  97                hr_min = readw(ioaddr + RTC_HOURMIN);
  98                sec = readw(ioaddr + RTC_SECOND);
  99                break;
 100        case MXC_RTC_ALARM:
 101                day = readw(ioaddr + RTC_DAYALARM);
 102                hr_min = readw(ioaddr + RTC_ALRM_HM) & 0xffff;
 103                sec = readw(ioaddr + RTC_ALRM_SEC);
 104                break;
 105        }
 106
 107        hr = hr_min >> 8;
 108        min = hr_min & 0xff;
 109
 110        return (((day * 24 + hr) * 60) + min) * 60 + sec;
 111}
 112
 113/*
 114 * This function sets the RTC alarm value or the time value.
 115 */
 116static void set_alarm_or_time(struct device *dev, int time_alarm, u32 time)
 117{
 118        u32 day, hr, min, sec, temp;
 119        struct platform_device *pdev = to_platform_device(dev);
 120        struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 121        void __iomem *ioaddr = pdata->ioaddr;
 122
 123        day = time / 86400;
 124        time -= day * 86400;
 125
 126        /* time is within a day now */
 127        hr = time / 3600;
 128        time -= hr * 3600;
 129
 130        /* time is within an hour now */
 131        min = time / 60;
 132        sec = time - min * 60;
 133
 134        temp = (hr << 8) + min;
 135
 136        switch (time_alarm) {
 137        case MXC_RTC_TIME:
 138                writew(day, ioaddr + RTC_DAYR);
 139                writew(sec, ioaddr + RTC_SECOND);
 140                writew(temp, ioaddr + RTC_HOURMIN);
 141                break;
 142        case MXC_RTC_ALARM:
 143                writew(day, ioaddr + RTC_DAYALARM);
 144                writew(sec, ioaddr + RTC_ALRM_SEC);
 145                writew(temp, ioaddr + RTC_ALRM_HM);
 146                break;
 147        }
 148}
 149
 150/*
 151 * This function updates the RTC alarm registers and then clears all the
 152 * interrupt status bits.
 153 */
 154static int rtc_update_alarm(struct device *dev, struct rtc_time *alrm)
 155{
 156        struct rtc_time alarm_tm, now_tm;
 157        unsigned long now, time;
 158        int ret;
 159        struct platform_device *pdev = to_platform_device(dev);
 160        struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 161        void __iomem *ioaddr = pdata->ioaddr;
 162
 163        now = get_alarm_or_time(dev, MXC_RTC_TIME);
 164        rtc_time_to_tm(now, &now_tm);
 165        alarm_tm.tm_year = now_tm.tm_year;
 166        alarm_tm.tm_mon = now_tm.tm_mon;
 167        alarm_tm.tm_mday = now_tm.tm_mday;
 168        alarm_tm.tm_hour = alrm->tm_hour;
 169        alarm_tm.tm_min = alrm->tm_min;
 170        alarm_tm.tm_sec = alrm->tm_sec;
 171        rtc_tm_to_time(&now_tm, &now);
 172        rtc_tm_to_time(&alarm_tm, &time);
 173
 174        if (time < now) {
 175                time += 60 * 60 * 24;
 176                rtc_time_to_tm(time, &alarm_tm);
 177        }
 178
 179        ret = rtc_tm_to_time(&alarm_tm, &time);
 180
 181        /* clear all the interrupt status bits */
 182        writew(readw(ioaddr + RTC_RTCISR), ioaddr + RTC_RTCISR);
 183        set_alarm_or_time(dev, MXC_RTC_ALARM, time);
 184
 185        return ret;
 186}
 187
 188/* This function is the RTC interrupt service routine. */
 189static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
 190{
 191        struct platform_device *pdev = dev_id;
 192        struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 193        void __iomem *ioaddr = pdata->ioaddr;
 194        u32 status;
 195        u32 events = 0;
 196
 197        spin_lock_irq(&pdata->rtc->irq_lock);
 198        status = readw(ioaddr + RTC_RTCISR) & readw(ioaddr + RTC_RTCIENR);
 199        /* clear interrupt sources */
 200        writew(status, ioaddr + RTC_RTCISR);
 201
 202        /* clear alarm interrupt if it has occurred */
 203        if (status & RTC_ALM_BIT)
 204                status &= ~RTC_ALM_BIT;
 205
 206        /* update irq data & counter */
 207        if (status & RTC_ALM_BIT)
 208                events |= (RTC_AF | RTC_IRQF);
 209
 210        if (status & RTC_1HZ_BIT)
 211                events |= (RTC_UF | RTC_IRQF);
 212
 213        if (status & PIT_ALL_ON)
 214                events |= (RTC_PF | RTC_IRQF);
 215
 216        if ((status & RTC_ALM_BIT) && rtc_valid_tm(&pdata->g_rtc_alarm))
 217                rtc_update_alarm(&pdev->dev, &pdata->g_rtc_alarm);
 218
 219        rtc_update_irq(pdata->rtc, 1, events);
 220        spin_unlock_irq(&pdata->rtc->irq_lock);
 221
 222        return IRQ_HANDLED;
 223}
 224
 225/*
 226 * Clear all interrupts and release the IRQ
 227 */
 228static void mxc_rtc_release(struct device *dev)
 229{
 230        struct platform_device *pdev = to_platform_device(dev);
 231        struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 232        void __iomem *ioaddr = pdata->ioaddr;
 233
 234        spin_lock_irq(&pdata->rtc->irq_lock);
 235
 236        /* Disable all rtc interrupts */
 237        writew(0, ioaddr + RTC_RTCIENR);
 238
 239        /* Clear all interrupt status */
 240        writew(0xffffffff, ioaddr + RTC_RTCISR);
 241
 242        spin_unlock_irq(&pdata->rtc->irq_lock);
 243}
 244
 245static void mxc_rtc_irq_enable(struct device *dev, unsigned int bit,
 246                                unsigned int enabled)
 247{
 248        struct platform_device *pdev = to_platform_device(dev);
 249        struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 250        void __iomem *ioaddr = pdata->ioaddr;
 251        u32 reg;
 252
 253        spin_lock_irq(&pdata->rtc->irq_lock);
 254        reg = readw(ioaddr + RTC_RTCIENR);
 255
 256        if (enabled)
 257                reg |= bit;
 258        else
 259                reg &= ~bit;
 260
 261        writew(reg, ioaddr + RTC_RTCIENR);
 262        spin_unlock_irq(&pdata->rtc->irq_lock);
 263}
 264
 265static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 266{
 267        mxc_rtc_irq_enable(dev, RTC_ALM_BIT, enabled);
 268        return 0;
 269}
 270
 271/*
 272 * This function reads the current RTC time into tm in Gregorian date.
 273 */
 274static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm)
 275{
 276        u32 val;
 277
 278        /* Avoid roll-over from reading the different registers */
 279        do {
 280                val = get_alarm_or_time(dev, MXC_RTC_TIME);
 281        } while (val != get_alarm_or_time(dev, MXC_RTC_TIME));
 282
 283        rtc_time_to_tm(val, tm);
 284
 285        return 0;
 286}
 287
 288/*
 289 * This function sets the internal RTC time based on tm in Gregorian date.
 290 */
 291static int mxc_rtc_set_mmss(struct device *dev, unsigned long time)
 292{
 293        /* Avoid roll-over from reading the different registers */
 294        do {
 295                set_alarm_or_time(dev, MXC_RTC_TIME, time);
 296        } while (time != get_alarm_or_time(dev, MXC_RTC_TIME));
 297
 298        return 0;
 299}
 300
 301/*
 302 * This function reads the current alarm value into the passed in 'alrm'
 303 * argument. It updates the alrm's pending field value based on the whether
 304 * an alarm interrupt occurs or not.
 305 */
 306static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 307{
 308        struct platform_device *pdev = to_platform_device(dev);
 309        struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 310        void __iomem *ioaddr = pdata->ioaddr;
 311
 312        rtc_time_to_tm(get_alarm_or_time(dev, MXC_RTC_ALARM), &alrm->time);
 313        alrm->pending = ((readw(ioaddr + RTC_RTCISR) & RTC_ALM_BIT)) ? 1 : 0;
 314
 315        return 0;
 316}
 317
 318/*
 319 * This function sets the RTC alarm based on passed in alrm.
 320 */
 321static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 322{
 323        struct platform_device *pdev = to_platform_device(dev);
 324        struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 325        int ret;
 326
 327        if (rtc_valid_tm(&alrm->time)) {
 328                if (alrm->time.tm_sec > 59 ||
 329                    alrm->time.tm_hour > 23 ||
 330                    alrm->time.tm_min > 59)
 331                        return -EINVAL;
 332
 333                ret = rtc_update_alarm(dev, &alrm->time);
 334        } else {
 335                ret = rtc_valid_tm(&alrm->time);
 336                if (ret)
 337                        return ret;
 338
 339                ret = rtc_update_alarm(dev, &alrm->time);
 340        }
 341
 342        if (ret)
 343                return ret;
 344
 345        memcpy(&pdata->g_rtc_alarm, &alrm->time, sizeof(struct rtc_time));
 346        mxc_rtc_irq_enable(dev, RTC_ALM_BIT, alrm->enabled);
 347
 348        return 0;
 349}
 350
 351/* RTC layer */
 352static struct rtc_class_ops mxc_rtc_ops = {
 353        .release                = mxc_rtc_release,
 354        .read_time              = mxc_rtc_read_time,
 355        .set_mmss               = mxc_rtc_set_mmss,
 356        .read_alarm             = mxc_rtc_read_alarm,
 357        .set_alarm              = mxc_rtc_set_alarm,
 358        .alarm_irq_enable       = mxc_rtc_alarm_irq_enable,
 359};
 360
 361static int __init mxc_rtc_probe(struct platform_device *pdev)
 362{
 363        struct resource *res;
 364        struct rtc_device *rtc;
 365        struct rtc_plat_data *pdata = NULL;
 366        u32 reg;
 367        unsigned long rate;
 368        int ret;
 369
 370        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 371        if (!res)
 372                return -ENODEV;
 373
 374        pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 375        if (!pdata)
 376                return -ENOMEM;
 377
 378        if (!devm_request_mem_region(&pdev->dev, res->start,
 379                                     resource_size(res), pdev->name))
 380                return -EBUSY;
 381
 382        pdata->ioaddr = devm_ioremap(&pdev->dev, res->start,
 383                                     resource_size(res));
 384
 385        pdata->clk = clk_get(&pdev->dev, "rtc");
 386        if (IS_ERR(pdata->clk)) {
 387                dev_err(&pdev->dev, "unable to get clock!\n");
 388                ret = PTR_ERR(pdata->clk);
 389                goto exit_free_pdata;
 390        }
 391
 392        clk_enable(pdata->clk);
 393        rate = clk_get_rate(pdata->clk);
 394
 395        if (rate == 32768)
 396                reg = RTC_INPUT_CLK_32768HZ;
 397        else if (rate == 32000)
 398                reg = RTC_INPUT_CLK_32000HZ;
 399        else if (rate == 38400)
 400                reg = RTC_INPUT_CLK_38400HZ;
 401        else {
 402                dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate);
 403                ret = -EINVAL;
 404                goto exit_put_clk;
 405        }
 406
 407        reg |= RTC_ENABLE_BIT;
 408        writew(reg, (pdata->ioaddr + RTC_RTCCTL));
 409        if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) {
 410                dev_err(&pdev->dev, "hardware module can't be enabled!\n");
 411                ret = -EIO;
 412                goto exit_put_clk;
 413        }
 414
 415        platform_set_drvdata(pdev, pdata);
 416
 417        /* Configure and enable the RTC */
 418        pdata->irq = platform_get_irq(pdev, 0);
 419
 420        if (pdata->irq >= 0 &&
 421            devm_request_irq(&pdev->dev, pdata->irq, mxc_rtc_interrupt,
 422                             IRQF_SHARED, pdev->name, pdev) < 0) {
 423                dev_warn(&pdev->dev, "interrupt not available.\n");
 424                pdata->irq = -1;
 425        }
 426
 427        rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops,
 428                                  THIS_MODULE);
 429        if (IS_ERR(rtc)) {
 430                ret = PTR_ERR(rtc);
 431                goto exit_clr_drvdata;
 432        }
 433
 434        pdata->rtc = rtc;
 435
 436        return 0;
 437
 438exit_clr_drvdata:
 439        platform_set_drvdata(pdev, NULL);
 440exit_put_clk:
 441        clk_disable(pdata->clk);
 442        clk_put(pdata->clk);
 443
 444exit_free_pdata:
 445
 446        return ret;
 447}
 448
 449static int __exit mxc_rtc_remove(struct platform_device *pdev)
 450{
 451        struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 452
 453        rtc_device_unregister(pdata->rtc);
 454
 455        clk_disable(pdata->clk);
 456        clk_put(pdata->clk);
 457        platform_set_drvdata(pdev, NULL);
 458
 459        return 0;
 460}
 461
 462static struct platform_driver mxc_rtc_driver = {
 463        .driver = {
 464                   .name        = "mxc_rtc",
 465                   .owner       = THIS_MODULE,
 466        },
 467        .remove         = __exit_p(mxc_rtc_remove),
 468};
 469
 470static int __init mxc_rtc_init(void)
 471{
 472        return platform_driver_probe(&mxc_rtc_driver, mxc_rtc_probe);
 473}
 474
 475static void __exit mxc_rtc_exit(void)
 476{
 477        platform_driver_unregister(&mxc_rtc_driver);
 478}
 479
 480module_init(mxc_rtc_init);
 481module_exit(mxc_rtc_exit);
 482
 483MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
 484MODULE_DESCRIPTION("RTC driver for Freescale MXC");
 485MODULE_LICENSE("GPL");
 486
 487
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.