rtc-uclass.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2015 Google, Inc
  4. * Written by Simon Glass <sjg@chromium.org>
  5. */
  6. #define LOG_CATEGORY UCLASS_RTC
  7. #include <common.h>
  8. #include <dm.h>
  9. #include <errno.h>
  10. #include <log.h>
  11. #include <rtc.h>
  12. int dm_rtc_get(struct udevice *dev, struct rtc_time *time)
  13. {
  14. struct rtc_ops *ops = rtc_get_ops(dev);
  15. assert(ops);
  16. if (!ops->get)
  17. return -ENOSYS;
  18. return ops->get(dev, time);
  19. }
  20. int dm_rtc_set(struct udevice *dev, struct rtc_time *time)
  21. {
  22. struct rtc_ops *ops = rtc_get_ops(dev);
  23. assert(ops);
  24. if (!ops->set)
  25. return -ENOSYS;
  26. return ops->set(dev, time);
  27. }
  28. int dm_rtc_reset(struct udevice *dev)
  29. {
  30. struct rtc_ops *ops = rtc_get_ops(dev);
  31. assert(ops);
  32. if (!ops->reset)
  33. return -ENOSYS;
  34. return ops->reset(dev);
  35. }
  36. int dm_rtc_read(struct udevice *dev, unsigned int reg, u8 *buf, unsigned int len)
  37. {
  38. struct rtc_ops *ops = rtc_get_ops(dev);
  39. assert(ops);
  40. if (ops->read)
  41. return ops->read(dev, reg, buf, len);
  42. if (!ops->read8)
  43. return -ENOSYS;
  44. while (len--) {
  45. int ret = ops->read8(dev, reg++);
  46. if (ret < 0)
  47. return ret;
  48. *buf++ = ret;
  49. }
  50. return 0;
  51. }
  52. int dm_rtc_write(struct udevice *dev, unsigned int reg,
  53. const u8 *buf, unsigned int len)
  54. {
  55. struct rtc_ops *ops = rtc_get_ops(dev);
  56. assert(ops);
  57. if (ops->write)
  58. return ops->write(dev, reg, buf, len);
  59. if (!ops->write8)
  60. return -ENOSYS;
  61. while (len--) {
  62. int ret = ops->write8(dev, reg++, *buf++);
  63. if (ret < 0)
  64. return ret;
  65. }
  66. return 0;
  67. }
  68. int rtc_read8(struct udevice *dev, unsigned int reg)
  69. {
  70. struct rtc_ops *ops = rtc_get_ops(dev);
  71. assert(ops);
  72. if (ops->read8)
  73. return ops->read8(dev, reg);
  74. if (ops->read) {
  75. u8 buf[1];
  76. int ret = ops->read(dev, reg, buf, 1);
  77. if (ret < 0)
  78. return ret;
  79. return buf[0];
  80. }
  81. return -ENOSYS;
  82. }
  83. int rtc_write8(struct udevice *dev, unsigned int reg, int val)
  84. {
  85. struct rtc_ops *ops = rtc_get_ops(dev);
  86. assert(ops);
  87. if (ops->write8)
  88. return ops->write8(dev, reg, val);
  89. if (ops->write) {
  90. u8 buf[1] = { val };
  91. return ops->write(dev, reg, buf, 1);
  92. }
  93. return -ENOSYS;
  94. }
  95. int rtc_read16(struct udevice *dev, unsigned int reg, u16 *valuep)
  96. {
  97. u16 value = 0;
  98. int ret;
  99. int i;
  100. for (i = 0; i < sizeof(value); i++) {
  101. ret = rtc_read8(dev, reg + i);
  102. if (ret < 0)
  103. return ret;
  104. value |= ret << (i << 3);
  105. }
  106. *valuep = value;
  107. return 0;
  108. }
  109. int rtc_write16(struct udevice *dev, unsigned int reg, u16 value)
  110. {
  111. int i, ret;
  112. for (i = 0; i < sizeof(value); i++) {
  113. ret = rtc_write8(dev, reg + i, (value >> (i << 3)) & 0xff);
  114. if (ret)
  115. return ret;
  116. }
  117. return 0;
  118. }
  119. int rtc_read32(struct udevice *dev, unsigned int reg, u32 *valuep)
  120. {
  121. u32 value = 0;
  122. int ret;
  123. int i;
  124. for (i = 0; i < sizeof(value); i++) {
  125. ret = rtc_read8(dev, reg + i);
  126. if (ret < 0)
  127. return ret;
  128. value |= ret << (i << 3);
  129. }
  130. *valuep = value;
  131. return 0;
  132. }
  133. int rtc_write32(struct udevice *dev, unsigned int reg, u32 value)
  134. {
  135. int i, ret;
  136. for (i = 0; i < sizeof(value); i++) {
  137. ret = rtc_write8(dev, reg + i, (value >> (i << 3)) & 0xff);
  138. if (ret)
  139. return ret;
  140. }
  141. return 0;
  142. }
  143. UCLASS_DRIVER(rtc) = {
  144. .name = "rtc",
  145. .id = UCLASS_RTC,
  146. #if !CONFIG_IS_ENABLED(OF_PLATDATA)
  147. .post_bind = dm_scan_fdt_dev,
  148. #endif
  149. };