rtc-uclass.c 3.1 KB

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