rtc-tps65910.c (12272B)
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:tps65910-rtc"); 471MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>"); 472MODULE_LICENSE("GPL");