rtc-da9052.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. * Real time clock driver for DA9052
  3. *
  4. * Copyright(c) 2012 Dialog Semiconductor Ltd.
  5. *
  6. * Author: Dajun Dajun Chen <dajun.chen@diasemi.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. */
  14. #include <linux/module.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/rtc.h>
  17. #include <linux/err.h>
  18. #include <linux/delay.h>
  19. #include <linux/mfd/da9052/da9052.h>
  20. #include <linux/mfd/da9052/reg.h>
  21. #define rtc_err(rtc, fmt, ...) \
  22. dev_err(rtc->da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__)
  23. #define DA9052_GET_TIME_RETRIES 5
  24. struct da9052_rtc {
  25. struct rtc_device *rtc;
  26. struct da9052 *da9052;
  27. };
  28. static int da9052_rtc_enable_alarm(struct da9052_rtc *rtc, bool enable)
  29. {
  30. int ret;
  31. if (enable) {
  32. ret = da9052_reg_update(rtc->da9052, DA9052_ALARM_Y_REG,
  33. DA9052_ALARM_Y_ALARM_ON|DA9052_ALARM_Y_TICK_ON,
  34. DA9052_ALARM_Y_ALARM_ON);
  35. if (ret != 0)
  36. rtc_err(rtc, "Failed to enable ALM: %d\n", ret);
  37. } else {
  38. ret = da9052_reg_update(rtc->da9052, DA9052_ALARM_Y_REG,
  39. DA9052_ALARM_Y_ALARM_ON|DA9052_ALARM_Y_TICK_ON, 0);
  40. if (ret != 0)
  41. rtc_err(rtc, "Write error: %d\n", ret);
  42. }
  43. return ret;
  44. }
  45. static irqreturn_t da9052_rtc_irq(int irq, void *data)
  46. {
  47. struct da9052_rtc *rtc = data;
  48. rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
  49. return IRQ_HANDLED;
  50. }
  51. static int da9052_read_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm)
  52. {
  53. int ret;
  54. uint8_t v[2][5];
  55. int idx = 1;
  56. int timeout = DA9052_GET_TIME_RETRIES;
  57. ret = da9052_group_read(rtc->da9052, DA9052_ALARM_MI_REG, 5, &v[0][0]);
  58. if (ret) {
  59. rtc_err(rtc, "Failed to group read ALM: %d\n", ret);
  60. return ret;
  61. }
  62. do {
  63. ret = da9052_group_read(rtc->da9052,
  64. DA9052_ALARM_MI_REG, 5, &v[idx][0]);
  65. if (ret) {
  66. rtc_err(rtc, "Failed to group read ALM: %d\n", ret);
  67. return ret;
  68. }
  69. if (memcmp(&v[0][0], &v[1][0], 5) == 0) {
  70. rtc_tm->tm_year = (v[0][4] & DA9052_RTC_YEAR) + 100;
  71. rtc_tm->tm_mon = (v[0][3] & DA9052_RTC_MONTH) - 1;
  72. rtc_tm->tm_mday = v[0][2] & DA9052_RTC_DAY;
  73. rtc_tm->tm_hour = v[0][1] & DA9052_RTC_HOUR;
  74. rtc_tm->tm_min = v[0][0] & DA9052_RTC_MIN;
  75. ret = rtc_valid_tm(rtc_tm);
  76. return ret;
  77. }
  78. idx = (1-idx);
  79. msleep(20);
  80. } while (timeout--);
  81. rtc_err(rtc, "Timed out reading alarm time\n");
  82. return -EIO;
  83. }
  84. static int da9052_set_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm)
  85. {
  86. struct da9052 *da9052 = rtc->da9052;
  87. unsigned long alm_time;
  88. int ret;
  89. uint8_t v[3];
  90. ret = rtc_tm_to_time(rtc_tm, &alm_time);
  91. if (ret != 0)
  92. return ret;
  93. if (rtc_tm->tm_sec > 0) {
  94. alm_time += 60 - rtc_tm->tm_sec;
  95. rtc_time_to_tm(alm_time, rtc_tm);
  96. }
  97. BUG_ON(rtc_tm->tm_sec); /* it will cause repeated irqs if not zero */
  98. rtc_tm->tm_year -= 100;
  99. rtc_tm->tm_mon += 1;
  100. ret = da9052_reg_update(da9052, DA9052_ALARM_MI_REG,
  101. DA9052_RTC_MIN, rtc_tm->tm_min);
  102. if (ret != 0) {
  103. rtc_err(rtc, "Failed to write ALRM MIN: %d\n", ret);
  104. return ret;
  105. }
  106. v[0] = rtc_tm->tm_hour;
  107. v[1] = rtc_tm->tm_mday;
  108. v[2] = rtc_tm->tm_mon;
  109. ret = da9052_group_write(da9052, DA9052_ALARM_H_REG, 3, v);
  110. if (ret < 0)
  111. return ret;
  112. ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG,
  113. DA9052_RTC_YEAR, rtc_tm->tm_year);
  114. if (ret != 0)
  115. rtc_err(rtc, "Failed to write ALRM YEAR: %d\n", ret);
  116. return ret;
  117. }
  118. static int da9052_rtc_get_alarm_status(struct da9052_rtc *rtc)
  119. {
  120. int ret;
  121. ret = da9052_reg_read(rtc->da9052, DA9052_ALARM_Y_REG);
  122. if (ret < 0) {
  123. rtc_err(rtc, "Failed to read ALM: %d\n", ret);
  124. return ret;
  125. }
  126. return !!(ret&DA9052_ALARM_Y_ALARM_ON);
  127. }
  128. static int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
  129. {
  130. struct da9052_rtc *rtc = dev_get_drvdata(dev);
  131. int ret;
  132. uint8_t v[2][6];
  133. int idx = 1;
  134. int timeout = DA9052_GET_TIME_RETRIES;
  135. ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, &v[0][0]);
  136. if (ret) {
  137. rtc_err(rtc, "Failed to read RTC time : %d\n", ret);
  138. return ret;
  139. }
  140. do {
  141. ret = da9052_group_read(rtc->da9052,
  142. DA9052_COUNT_S_REG, 6, &v[idx][0]);
  143. if (ret) {
  144. rtc_err(rtc, "Failed to read RTC time : %d\n", ret);
  145. return ret;
  146. }
  147. if (memcmp(&v[0][0], &v[1][0], 6) == 0) {
  148. rtc_tm->tm_year = (v[0][5] & DA9052_RTC_YEAR) + 100;
  149. rtc_tm->tm_mon = (v[0][4] & DA9052_RTC_MONTH) - 1;
  150. rtc_tm->tm_mday = v[0][3] & DA9052_RTC_DAY;
  151. rtc_tm->tm_hour = v[0][2] & DA9052_RTC_HOUR;
  152. rtc_tm->tm_min = v[0][1] & DA9052_RTC_MIN;
  153. rtc_tm->tm_sec = v[0][0] & DA9052_RTC_SEC;
  154. ret = rtc_valid_tm(rtc_tm);
  155. return ret;
  156. }
  157. idx = (1-idx);
  158. msleep(20);
  159. } while (timeout--);
  160. rtc_err(rtc, "Timed out reading time\n");
  161. return -EIO;
  162. }
  163. static int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm)
  164. {
  165. struct da9052_rtc *rtc;
  166. uint8_t v[6];
  167. int ret;
  168. /* DA9052 only has 6 bits for year - to represent 2000-2063 */
  169. if ((tm->tm_year < 100) || (tm->tm_year > 163))
  170. return -EINVAL;
  171. rtc = dev_get_drvdata(dev);
  172. v[0] = tm->tm_sec;
  173. v[1] = tm->tm_min;
  174. v[2] = tm->tm_hour;
  175. v[3] = tm->tm_mday;
  176. v[4] = tm->tm_mon + 1;
  177. v[5] = tm->tm_year - 100;
  178. ret = da9052_group_write(rtc->da9052, DA9052_COUNT_S_REG, 6, v);
  179. if (ret < 0)
  180. rtc_err(rtc, "failed to set RTC time: %d\n", ret);
  181. return ret;
  182. }
  183. static int da9052_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
  184. {
  185. int ret;
  186. struct rtc_time *tm = &alrm->time;
  187. struct da9052_rtc *rtc = dev_get_drvdata(dev);
  188. ret = da9052_read_alarm(rtc, tm);
  189. if (ret < 0) {
  190. rtc_err(rtc, "failed to read RTC alarm: %d\n", ret);
  191. return ret;
  192. }
  193. alrm->enabled = da9052_rtc_get_alarm_status(rtc);
  194. return 0;
  195. }
  196. static int da9052_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
  197. {
  198. int ret;
  199. struct rtc_time *tm = &alrm->time;
  200. struct da9052_rtc *rtc = dev_get_drvdata(dev);
  201. /* DA9052 only has 6 bits for year - to represent 2000-2063 */
  202. if ((tm->tm_year < 100) || (tm->tm_year > 163))
  203. return -EINVAL;
  204. ret = da9052_rtc_enable_alarm(rtc, 0);
  205. if (ret < 0)
  206. return ret;
  207. ret = da9052_set_alarm(rtc, tm);
  208. if (ret < 0)
  209. return ret;
  210. ret = da9052_rtc_enable_alarm(rtc, 1);
  211. return ret;
  212. }
  213. static int da9052_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
  214. {
  215. struct da9052_rtc *rtc = dev_get_drvdata(dev);
  216. return da9052_rtc_enable_alarm(rtc, enabled);
  217. }
  218. static const struct rtc_class_ops da9052_rtc_ops = {
  219. .read_time = da9052_rtc_read_time,
  220. .set_time = da9052_rtc_set_time,
  221. .read_alarm = da9052_rtc_read_alarm,
  222. .set_alarm = da9052_rtc_set_alarm,
  223. .alarm_irq_enable = da9052_rtc_alarm_irq_enable,
  224. };
  225. static int da9052_rtc_probe(struct platform_device *pdev)
  226. {
  227. struct da9052_rtc *rtc;
  228. int ret;
  229. rtc = devm_kzalloc(&pdev->dev, sizeof(struct da9052_rtc), GFP_KERNEL);
  230. if (!rtc)
  231. return -ENOMEM;
  232. rtc->da9052 = dev_get_drvdata(pdev->dev.parent);
  233. platform_set_drvdata(pdev, rtc);
  234. ret = da9052_reg_write(rtc->da9052, DA9052_BBAT_CONT_REG, 0xFE);
  235. if (ret < 0) {
  236. rtc_err(rtc,
  237. "Failed to setup RTC battery charging: %d\n", ret);
  238. return ret;
  239. }
  240. ret = da9052_reg_update(rtc->da9052, DA9052_ALARM_Y_REG,
  241. DA9052_ALARM_Y_TICK_ON, 0);
  242. if (ret != 0)
  243. rtc_err(rtc, "Failed to disable TICKS: %d\n", ret);
  244. ret = da9052_request_irq(rtc->da9052, DA9052_IRQ_ALARM, "ALM",
  245. da9052_rtc_irq, rtc);
  246. if (ret != 0) {
  247. rtc_err(rtc, "irq registration failed: %d\n", ret);
  248. return ret;
  249. }
  250. device_init_wakeup(&pdev->dev, true);
  251. rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
  252. &da9052_rtc_ops, THIS_MODULE);
  253. return PTR_ERR_OR_ZERO(rtc->rtc);
  254. }
  255. static struct platform_driver da9052_rtc_driver = {
  256. .probe = da9052_rtc_probe,
  257. .driver = {
  258. .name = "da9052-rtc",
  259. },
  260. };
  261. module_platform_driver(da9052_rtc_driver);
  262. MODULE_AUTHOR("Anthony Olech <Anthony.Olech@diasemi.com>");
  263. MODULE_DESCRIPTION("RTC driver for Dialog DA9052 PMIC");
  264. MODULE_LICENSE("GPL");
  265. MODULE_ALIAS("platform:da9052-rtc");