linux/drivers/rtc/rtc-tps65910.c
<<
>>
Prefs
   1/*
   2 * rtc-tps65910.c -- TPS65910 Real Time Clock interface
   3 *
   4 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
   5 * Author: Venu Byravarasu <vbyravarasu@nvidia.com>
   6 *
   7 * Based on original TI driver rtc-twl.c
   8 *   Copyright (C) 2007 MontaVista Software, Inc
   9 *   Author: Alexandre Rusev <source@mvista.com>
  10 *
  11 * This program is free software; you can redistribute it and/or
  12 * modify it under the terms of the GNU General Public License
  13 * as published by the Free Software Foundation; either version
  14 * 2 of the License, or (at your option) any later version.
  15 */
  16
  17#include <linux/kernel.h>
  18#include <linux/errno.h>
  19#include <linux/init.h>
  20#include <linux/module.h>
  21#include <linux/types.h>
  22#include <linux/rtc.h>
  23#include <linux/bcd.h>
  24#include <linux/math64.h>
  25#include <linux/platform_device.h>
  26#include <linux/interrupt.h>
  27#include <linux/mfd/tps65910.h>
  28
  29struct tps65910_rtc {
  30        struct rtc_device       *rtc;
  31        int irq;
  32};
  33
  34/* Total number of RTC registers needed to set time*/
  35#define NUM_TIME_REGS   (TPS65910_YEARS - TPS65910_SECONDS + 1)
  36
  37/* Total number of RTC registers needed to set compensation registers */
  38#define NUM_COMP_REGS   (TPS65910_RTC_COMP_MSB - TPS65910_RTC_COMP_LSB + 1)
  39
  40/* Min and max values supported with 'offset' interface (swapped sign) */
  41#define MIN_OFFSET      (-277761)
  42#define MAX_OFFSET      (277778)
  43
  44/* Number of ticks per hour */
  45#define TICKS_PER_HOUR  (32768 * 3600)
  46
  47/* Multiplier for ppb conversions */
  48#define PPB_MULT        (1000000000LL)
  49
  50static int tps65910_rtc_alarm_irq_enable(struct device *dev,
  51                                         unsigned int enabled)
  52{
  53        struct tps65910 *tps = dev_get_drvdata(dev->parent);
  54        u8 val = 0;
  55
  56        if (enabled)
  57                val = TPS65910_RTC_INTERRUPTS_IT_ALARM;
  58
  59        return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, val);
  60}
  61
  62/*
  63 * Gets current tps65910 RTC time and date parameters.
  64 *
  65 * The RTC's time/alarm representation is not what gmtime(3) requires
  66 * Linux to use:
  67 *
  68 *  - Months are 1..12 vs Linux 0-11
  69 *  - Years are 0..99 vs Linux 1900..N (we assume 21st century)
  70 */
  71static int tps65910_rtc_read_time(struct device *dev, struct rtc_time *tm)
  72{
  73        unsigned char rtc_data[NUM_TIME_REGS];
  74        struct tps65910 *tps = dev_get_drvdata(dev->parent);
  75        int ret;
  76
  77        /* Copy RTC counting registers to static registers or latches */
  78        ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL,
  79                TPS65910_RTC_CTRL_GET_TIME, TPS65910_RTC_CTRL_GET_TIME);
  80        if (ret < 0) {
  81                dev_err(dev, "RTC CTRL reg update failed with err:%d\n", ret);
  82                return ret;
  83        }
  84
  85        ret = regmap_bulk_read(tps->regmap, TPS65910_SECONDS, rtc_data,
  86                NUM_TIME_REGS);
  87        if (ret < 0) {
  88                dev_err(dev, "reading from RTC failed with err:%d\n", ret);
  89                return ret;
  90        }
  91
  92        tm->tm_sec = bcd2bin(rtc_data[0]);
  93        tm->tm_min = bcd2bin(rtc_data[1]);
  94        tm->tm_hour = bcd2bin(rtc_data[2]);
  95        tm->tm_mday = bcd2bin(rtc_data[3]);
  96        tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
  97        tm->tm_year = bcd2bin(rtc_data[5]) + 100;
  98
  99        return ret;
 100}
 101
 102static int tps65910_rtc_set_time(struct device *dev, struct rtc_time *tm)
 103{
 104        unsigned char rtc_data[NUM_TIME_REGS];
 105        struct tps65910 *tps = dev_get_drvdata(dev->parent);
 106        int ret;
 107
 108        rtc_data[0] = bin2bcd(tm->tm_sec);
 109        rtc_data[1] = bin2bcd(tm->tm_min);
 110        rtc_data[2] = bin2bcd(tm->tm_hour);
 111        rtc_data[3] = bin2bcd(tm->tm_mday);
 112        rtc_data[4] = bin2bcd(tm->tm_mon + 1);
 113        rtc_data[5] = bin2bcd(tm->tm_year - 100);
 114
 115        /* Stop RTC while updating the RTC time registers */
 116        ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL,
 117                TPS65910_RTC_CTRL_STOP_RTC, 0);
 118        if (ret < 0) {
 119                dev_err(dev, "RTC stop failed with err:%d\n", ret);
 120                return ret;
 121        }
 122
 123        /* update all the time registers in one shot */
 124        ret = regmap_bulk_write(tps->regmap, TPS65910_SECONDS, rtc_data,
 125                NUM_TIME_REGS);
 126        if (ret < 0) {
 127                dev_err(dev, "rtc_set_time error %d\n", ret);
 128                return ret;
 129        }
 130
 131        /* Start back RTC */
 132        ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL,
 133                TPS65910_RTC_CTRL_STOP_RTC, 1);
 134        if (ret < 0)
 135                dev_err(dev, "RTC start failed with err:%d\n", ret);
 136
 137        return ret;
 138}
 139
 140/*
 141 * Gets current tps65910 RTC alarm time.
 142 */
 143static int tps65910_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
 144{
 145        unsigned char alarm_data[NUM_TIME_REGS];
 146        u32 int_val;
 147        struct tps65910 *tps = dev_get_drvdata(dev->parent);
 148        int ret;
 149
 150        ret = regmap_bulk_read(tps->regmap, TPS65910_SECONDS, alarm_data,
 151                NUM_TIME_REGS);
 152        if (ret < 0) {
 153                dev_err(dev, "rtc_read_alarm error %d\n", ret);
 154                return ret;
 155        }
 156
 157        alm->time.tm_sec = bcd2bin(alarm_data[0]);
 158        alm->time.tm_min = bcd2bin(alarm_data[1]);
 159        alm->time.tm_hour = bcd2bin(alarm_data[2]);
 160        alm->time.tm_mday = bcd2bin(alarm_data[3]);
 161        alm->time.tm_mon = bcd2bin(alarm_data[4]) - 1;
 162        alm->time.tm_year = bcd2bin(alarm_data[5]) + 100;
 163
 164        ret = regmap_read(tps->regmap, TPS65910_RTC_INTERRUPTS, &int_val);
 165        if (ret < 0)
 166                return ret;
 167
 168        if (int_val & TPS65910_RTC_INTERRUPTS_IT_ALARM)
 169                alm->enabled = 1;
 170
 171        return ret;
 172}
 173
 174static int tps65910_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 175{
 176        unsigned char alarm_data[NUM_TIME_REGS];
 177        struct tps65910 *tps = dev_get_drvdata(dev->parent);
 178        int ret;
 179
 180        ret = tps65910_rtc_alarm_irq_enable(dev, 0);
 181        if (ret)
 182                return ret;
 183
 184        alarm_data[0] = bin2bcd(alm->time.tm_sec);
 185        alarm_data[1] = bin2bcd(alm->time.tm_min);
 186        alarm_data[2] = bin2bcd(alm->time.tm_hour);
 187        alarm_data[3] = bin2bcd(alm->time.tm_mday);
 188        alarm_data[4] = bin2bcd(alm->time.tm_mon + 1);
 189        alarm_data[5] = bin2bcd(alm->time.tm_year - 100);
 190
 191        /* update all the alarm registers in one shot */
 192        ret = regmap_bulk_write(tps->regmap, TPS65910_ALARM_SECONDS,
 193                alarm_data, NUM_TIME_REGS);
 194        if (ret) {
 195                dev_err(dev, "rtc_set_alarm error %d\n", ret);
 196                return ret;
 197        }
 198
 199        if (alm->enabled)
 200                ret = tps65910_rtc_alarm_irq_enable(dev, 1);
 201
 202        return ret;
 203}
 204
 205static int tps65910_rtc_set_calibration(struct device *dev, int calibration)
 206{
 207        unsigned char comp_data[NUM_COMP_REGS];
 208        struct tps65910 *tps = dev_get_drvdata(dev->parent);
 209        s16 value;
 210        int ret;
 211
 212        /*
 213         * TPS65910 uses two's complement 16 bit value for compensation for RTC
 214         * crystal inaccuracies. One time every hour when seconds counter
 215         * increments from 0 to 1 compensation value will be added to internal
 216         * RTC counter value.
 217         *
 218         * Compensation value 0x7FFF is prohibited value.
 219         *
 220         * Valid range for compensation value: [-32768 .. 32766]
 221         */
 222        if ((calibration < -32768) || (calibration > 32766)) {
 223                dev_err(dev, "RTC calibration value out of range: %d\n",
 224                        calibration);
 225                return -EINVAL;
 226        }
 227
 228        value = (s16)calibration;
 229
 230        comp_data[0] = (u16)value & 0xFF;
 231        comp_data[1] = ((u16)value >> 8) & 0xFF;
 232
 233        /* Update all the compensation registers in one shot */
 234        ret = regmap_bulk_write(tps->regmap, TPS65910_RTC_COMP_LSB,
 235                comp_data, NUM_COMP_REGS);
 236        if (ret < 0) {
 237                dev_err(dev, "rtc_set_calibration error: %d\n", ret);
 238                return ret;
 239        }
 240
 241        /* Enable automatic compensation */
 242        ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL,
 243                TPS65910_RTC_CTRL_AUTO_COMP, TPS65910_RTC_CTRL_AUTO_COMP);
 244        if (ret < 0)
 245                dev_err(dev, "auto_comp enable failed with error: %d\n", ret);
 246
 247        return ret;
 248}
 249
 250static int tps65910_rtc_get_calibration(struct device *dev, int *calibration)
 251{
 252        unsigned char comp_data[NUM_COMP_REGS];
 253        struct tps65910 *tps = dev_get_drvdata(dev->parent);
 254        unsigned int ctrl;
 255        u16 value;
 256        int ret;
 257
 258        ret = regmap_read(tps->regmap, TPS65910_RTC_CTRL, &ctrl);
 259        if (ret < 0)
 260                return ret;
 261
 262        /* If automatic compensation is not enabled report back zero */
 263        if (!(ctrl & TPS65910_RTC_CTRL_AUTO_COMP)) {
 264                *calibration = 0;
 265                return 0;
 266        }
 267
 268        ret = regmap_bulk_read(tps->regmap, TPS65910_RTC_COMP_LSB, comp_data,
 269                NUM_COMP_REGS);
 270        if (ret < 0) {
 271                dev_err(dev, "rtc_get_calibration error: %d\n", ret);
 272                return ret;
 273        }
 274
 275        value = (u16)comp_data[0] | ((u16)comp_data[1] << 8);
 276
 277        *calibration = (s16)value;
 278
 279        return 0;
 280}
 281
 282static int tps65910_read_offset(struct device *dev, long *offset)
 283{
 284        int calibration;
 285        s64 tmp;
 286        int ret;
 287
 288        ret = tps65910_rtc_get_calibration(dev, &calibration);
 289        if (ret < 0)
 290                return ret;
 291
 292        /* Convert from RTC calibration register format to ppb format */
 293        tmp = calibration * (s64)PPB_MULT;
 294        if (tmp < 0)
 295                tmp -= TICKS_PER_HOUR / 2LL;
 296        else
 297                tmp += TICKS_PER_HOUR / 2LL;
 298        tmp = div_s64(tmp, TICKS_PER_HOUR);
 299
 300        /* Offset value operates in negative way, so swap sign */
 301        *offset = (long)-tmp;
 302
 303        return 0;
 304}
 305
 306static int tps65910_set_offset(struct device *dev, long offset)
 307{
 308        int calibration;
 309        s64 tmp;
 310        int ret;
 311
 312        /* Make sure offset value is within supported range */
 313        if (offset < MIN_OFFSET || offset > MAX_OFFSET)
 314                return -ERANGE;
 315
 316        /* Convert from ppb format to RTC calibration register format */
 317        tmp = offset * (s64)TICKS_PER_HOUR;
 318        if (tmp < 0)
 319                tmp -= PPB_MULT / 2LL;
 320        else
 321                tmp += PPB_MULT / 2LL;
 322        tmp = div_s64(tmp, PPB_MULT);
 323
 324        /* Offset value operates in negative way, so swap sign */
 325        calibration = (int)-tmp;
 326
 327        ret = tps65910_rtc_set_calibration(dev, calibration);
 328
 329        return ret;
 330}
 331
 332static irqreturn_t tps65910_rtc_interrupt(int irq, void *rtc)
 333{
 334        struct device *dev = rtc;
 335        unsigned long events = 0;
 336        struct tps65910 *tps = dev_get_drvdata(dev->parent);
 337        struct tps65910_rtc *tps_rtc = dev_get_drvdata(dev);
 338        int ret;
 339        u32 rtc_reg;
 340
 341        ret = regmap_read(tps->regmap, TPS65910_RTC_STATUS, &rtc_reg);
 342        if (ret)
 343                return IRQ_NONE;
 344
 345        if (rtc_reg & TPS65910_RTC_STATUS_ALARM)
 346                events = RTC_IRQF | RTC_AF;
 347
 348        ret = regmap_write(tps->regmap, TPS65910_RTC_STATUS, rtc_reg);
 349        if (ret)
 350                return IRQ_NONE;
 351
 352        /* Notify RTC core on event */
 353        rtc_update_irq(tps_rtc->rtc, 1, events);
 354
 355        return IRQ_HANDLED;
 356}
 357
 358static const struct rtc_class_ops tps65910_rtc_ops = {
 359        .read_time      = tps65910_rtc_read_time,
 360        .set_time       = tps65910_rtc_set_time,
 361        .read_alarm     = tps65910_rtc_read_alarm,
 362        .set_alarm      = tps65910_rtc_set_alarm,
 363        .alarm_irq_enable = tps65910_rtc_alarm_irq_enable,
 364        .read_offset    = tps65910_read_offset,
 365        .set_offset     = tps65910_set_offset,
 366};
 367
 368static int tps65910_rtc_probe(struct platform_device *pdev)
 369{
 370        struct tps65910 *tps65910 = NULL;
 371        struct tps65910_rtc *tps_rtc = NULL;
 372        int ret;
 373        int irq;
 374        u32 rtc_reg;
 375
 376        tps65910 = dev_get_drvdata(pdev->dev.parent);
 377
 378        tps_rtc = devm_kzalloc(&pdev->dev, sizeof(struct tps65910_rtc),
 379                        GFP_KERNEL);
 380        if (!tps_rtc)
 381                return -ENOMEM;
 382
 383        /* Clear pending interrupts */
 384        ret = regmap_read(tps65910->regmap, TPS65910_RTC_STATUS, &rtc_reg);
 385        if (ret < 0)
 386                return ret;
 387
 388        ret = regmap_write(tps65910->regmap, TPS65910_RTC_STATUS, rtc_reg);
 389        if (ret < 0)
 390                return ret;
 391
 392        dev_dbg(&pdev->dev, "Enabling rtc-tps65910.\n");
 393
 394        /* Enable RTC digital power domain */
 395        ret = regmap_update_bits(tps65910->regmap, TPS65910_DEVCTRL,
 396                DEVCTRL_RTC_PWDN_MASK, 0 << DEVCTRL_RTC_PWDN_SHIFT);
 397        if (ret < 0)
 398                return ret;
 399
 400        rtc_reg = TPS65910_RTC_CTRL_STOP_RTC;
 401        ret = regmap_write(tps65910->regmap, TPS65910_RTC_CTRL, rtc_reg);
 402        if (ret < 0)
 403                return ret;
 404
 405        platform_set_drvdata(pdev, tps_rtc);
 406
 407        irq  = platform_get_irq(pdev, 0);
 408        if (irq <= 0) {
 409                dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n",
 410                        irq);
 411                return -ENXIO;
 412        }
 413
 414        ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
 415                tps65910_rtc_interrupt, IRQF_TRIGGER_LOW,
 416                dev_name(&pdev->dev), &pdev->dev);
 417        if (ret < 0) {
 418                dev_err(&pdev->dev, "IRQ is not free.\n");
 419                return ret;
 420        }
 421        tps_rtc->irq = irq;
 422        device_set_wakeup_capable(&pdev->dev, 1);
 423
 424        tps_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
 425                &tps65910_rtc_ops, THIS_MODULE);
 426        if (IS_ERR(tps_rtc->rtc)) {
 427                ret = PTR_ERR(tps_rtc->rtc);
 428                dev_err(&pdev->dev, "RTC device register: err %d\n", ret);
 429                return ret;
 430        }
 431
 432        return 0;
 433}
 434
 435/*
 436 * Disable tps65910 RTC interrupts.
 437 * Sets status flag to free.
 438 */
 439static int tps65910_rtc_remove(struct platform_device *pdev)
 440{
 441        tps65910_rtc_alarm_irq_enable(&pdev->dev, 0);
 442
 443        return 0;
 444}
 445
 446#ifdef CONFIG_PM_SLEEP
 447static int tps65910_rtc_suspend(struct device *dev)
 448{
 449        struct tps65910_rtc *tps_rtc = dev_get_drvdata(dev);
 450
 451        if (device_may_wakeup(dev))
 452                enable_irq_wake(tps_rtc->irq);
 453        return 0;
 454}
 455
 456static int tps65910_rtc_resume(struct device *dev)
 457{
 458        struct tps65910_rtc *tps_rtc = dev_get_drvdata(dev);
 459
 460        if (device_may_wakeup(dev))
 461                disable_irq_wake(tps_rtc->irq);
 462        return 0;
 463}
 464#endif
 465
 466static SIMPLE_DEV_PM_OPS(tps65910_rtc_pm_ops, tps65910_rtc_suspend,
 467                        tps65910_rtc_resume);
 468
 469static struct platform_driver tps65910_rtc_driver = {
 470        .probe          = tps65910_rtc_probe,
 471        .remove         = tps65910_rtc_remove,
 472        .driver         = {
 473                .name   = "tps65910-rtc",
 474                .pm     = &tps65910_rtc_pm_ops,
 475        },
 476};
 477
 478module_platform_driver(tps65910_rtc_driver);
 479MODULE_ALIAS("platform:rtc-tps65910");
 480MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>");
 481MODULE_LICENSE("GPL");
 482