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