rtc-digicolor.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * Real Time Clock driver for Conexant Digicolor
  3. *
  4. * Copyright (C) 2015 Paradox Innovation Ltd.
  5. *
  6. * Author: Baruch Siach <baruch@tkos.co.il>
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2 of the License, or (at your
  11. * option) any later version.
  12. */
  13. #include <linux/io.h>
  14. #include <linux/iopoll.h>
  15. #include <linux/delay.h>
  16. #include <linux/module.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/rtc.h>
  19. #include <linux/of.h>
  20. #define DC_RTC_CONTROL 0x0
  21. #define DC_RTC_TIME 0x8
  22. #define DC_RTC_REFERENCE 0xc
  23. #define DC_RTC_ALARM 0x10
  24. #define DC_RTC_INTFLAG_CLEAR 0x14
  25. #define DC_RTC_INTENABLE 0x16
  26. #define DC_RTC_CMD_MASK 0xf
  27. #define DC_RTC_GO_BUSY BIT(7)
  28. #define CMD_NOP 0
  29. #define CMD_RESET 1
  30. #define CMD_WRITE 3
  31. #define CMD_READ 4
  32. #define CMD_DELAY_US (10*1000)
  33. #define CMD_TIMEOUT_US (500*CMD_DELAY_US)
  34. struct dc_rtc {
  35. struct rtc_device *rtc_dev;
  36. void __iomem *regs;
  37. };
  38. static int dc_rtc_cmds(struct dc_rtc *rtc, const u8 *cmds, int len)
  39. {
  40. u8 val;
  41. int i, ret;
  42. for (i = 0; i < len; i++) {
  43. writeb_relaxed((cmds[i] & DC_RTC_CMD_MASK) | DC_RTC_GO_BUSY,
  44. rtc->regs + DC_RTC_CONTROL);
  45. ret = readb_relaxed_poll_timeout(
  46. rtc->regs + DC_RTC_CONTROL, val,
  47. !(val & DC_RTC_GO_BUSY), CMD_DELAY_US, CMD_TIMEOUT_US);
  48. if (ret < 0)
  49. return ret;
  50. }
  51. return 0;
  52. }
  53. static int dc_rtc_read(struct dc_rtc *rtc, unsigned long *val)
  54. {
  55. static const u8 read_cmds[] = {CMD_READ, CMD_NOP};
  56. u32 reference, time1, time2;
  57. int ret;
  58. ret = dc_rtc_cmds(rtc, read_cmds, ARRAY_SIZE(read_cmds));
  59. if (ret < 0)
  60. return ret;
  61. reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE);
  62. time1 = readl_relaxed(rtc->regs + DC_RTC_TIME);
  63. /* Read twice to ensure consistency */
  64. while (1) {
  65. time2 = readl_relaxed(rtc->regs + DC_RTC_TIME);
  66. if (time1 == time2)
  67. break;
  68. time1 = time2;
  69. }
  70. *val = reference + time1;
  71. return 0;
  72. }
  73. static int dc_rtc_write(struct dc_rtc *rtc, u32 val)
  74. {
  75. static const u8 write_cmds[] = {CMD_WRITE, CMD_NOP, CMD_RESET, CMD_NOP};
  76. writel_relaxed(val, rtc->regs + DC_RTC_REFERENCE);
  77. return dc_rtc_cmds(rtc, write_cmds, ARRAY_SIZE(write_cmds));
  78. }
  79. static int dc_rtc_read_time(struct device *dev, struct rtc_time *tm)
  80. {
  81. struct dc_rtc *rtc = dev_get_drvdata(dev);
  82. unsigned long now;
  83. int ret;
  84. ret = dc_rtc_read(rtc, &now);
  85. if (ret < 0)
  86. return ret;
  87. rtc_time64_to_tm(now, tm);
  88. return 0;
  89. }
  90. static int dc_rtc_set_mmss(struct device *dev, unsigned long secs)
  91. {
  92. struct dc_rtc *rtc = dev_get_drvdata(dev);
  93. return dc_rtc_write(rtc, secs);
  94. }
  95. static int dc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
  96. {
  97. struct dc_rtc *rtc = dev_get_drvdata(dev);
  98. u32 alarm_reg, reference;
  99. unsigned long now;
  100. int ret;
  101. alarm_reg = readl_relaxed(rtc->regs + DC_RTC_ALARM);
  102. reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE);
  103. rtc_time64_to_tm(reference + alarm_reg, &alarm->time);
  104. ret = dc_rtc_read(rtc, &now);
  105. if (ret < 0)
  106. return ret;
  107. alarm->pending = alarm_reg + reference > now;
  108. alarm->enabled = readl_relaxed(rtc->regs + DC_RTC_INTENABLE);
  109. return 0;
  110. }
  111. static int dc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
  112. {
  113. struct dc_rtc *rtc = dev_get_drvdata(dev);
  114. time64_t alarm_time;
  115. u32 reference;
  116. alarm_time = rtc_tm_to_time64(&alarm->time);
  117. reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE);
  118. writel_relaxed(alarm_time - reference, rtc->regs + DC_RTC_ALARM);
  119. writeb_relaxed(!!alarm->enabled, rtc->regs + DC_RTC_INTENABLE);
  120. return 0;
  121. }
  122. static int dc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
  123. {
  124. struct dc_rtc *rtc = dev_get_drvdata(dev);
  125. writeb_relaxed(!!enabled, rtc->regs + DC_RTC_INTENABLE);
  126. return 0;
  127. }
  128. static const struct rtc_class_ops dc_rtc_ops = {
  129. .read_time = dc_rtc_read_time,
  130. .set_mmss = dc_rtc_set_mmss,
  131. .read_alarm = dc_rtc_read_alarm,
  132. .set_alarm = dc_rtc_set_alarm,
  133. .alarm_irq_enable = dc_rtc_alarm_irq_enable,
  134. };
  135. static irqreturn_t dc_rtc_irq(int irq, void *dev_id)
  136. {
  137. struct dc_rtc *rtc = dev_id;
  138. writeb_relaxed(1, rtc->regs + DC_RTC_INTFLAG_CLEAR);
  139. rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
  140. return IRQ_HANDLED;
  141. }
  142. static int __init dc_rtc_probe(struct platform_device *pdev)
  143. {
  144. struct resource *res;
  145. struct dc_rtc *rtc;
  146. int irq, ret;
  147. rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
  148. if (!rtc)
  149. return -ENOMEM;
  150. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  151. rtc->regs = devm_ioremap_resource(&pdev->dev, res);
  152. if (IS_ERR(rtc->regs))
  153. return PTR_ERR(rtc->regs);
  154. irq = platform_get_irq(pdev, 0);
  155. if (irq < 0)
  156. return irq;
  157. ret = devm_request_irq(&pdev->dev, irq, dc_rtc_irq, 0, pdev->name, rtc);
  158. if (ret < 0)
  159. return ret;
  160. platform_set_drvdata(pdev, rtc);
  161. rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
  162. &dc_rtc_ops, THIS_MODULE);
  163. if (IS_ERR(rtc->rtc_dev))
  164. return PTR_ERR(rtc->rtc_dev);
  165. return 0;
  166. }
  167. static const struct of_device_id dc_dt_ids[] = {
  168. { .compatible = "cnxt,cx92755-rtc" },
  169. { /* sentinel */ }
  170. };
  171. MODULE_DEVICE_TABLE(of, dc_dt_ids);
  172. static struct platform_driver dc_rtc_driver = {
  173. .driver = {
  174. .name = "digicolor_rtc",
  175. .of_match_table = of_match_ptr(dc_dt_ids),
  176. },
  177. };
  178. module_platform_driver_probe(dc_rtc_driver, dc_rtc_probe);
  179. MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
  180. MODULE_DESCRIPTION("Conexant Digicolor Realtime Clock Driver (RTC)");
  181. MODULE_LICENSE("GPL");