PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/rtc/rtc-tps65910.c

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