rtc.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2015 Google, Inc
  4. * Written by Simon Glass <sjg@chromium.org>
  5. */
  6. #include <common.h>
  7. #include <dm.h>
  8. #include <i2c.h>
  9. #include <rtc.h>
  10. #include <asm/io.h>
  11. #include <asm/test.h>
  12. #include <dm/test.h>
  13. #include <test/ut.h>
  14. /* Simple RTC sanity check */
  15. static int dm_test_rtc_base(struct unit_test_state *uts)
  16. {
  17. struct udevice *dev;
  18. ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_RTC, 2, &dev));
  19. ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
  20. ut_assertok(uclass_get_device(UCLASS_RTC, 1, &dev));
  21. return 0;
  22. }
  23. DM_TEST(dm_test_rtc_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
  24. static void show_time(const char *msg, struct rtc_time *time)
  25. {
  26. printf("%s: %02d/%02d/%04d %02d:%02d:%02d\n", msg,
  27. time->tm_mday, time->tm_mon, time->tm_year,
  28. time->tm_hour, time->tm_min, time->tm_sec);
  29. }
  30. static int cmp_times(struct rtc_time *expect, struct rtc_time *time, bool show)
  31. {
  32. bool same;
  33. same = expect->tm_sec == time->tm_sec;
  34. same &= expect->tm_min == time->tm_min;
  35. same &= expect->tm_hour == time->tm_hour;
  36. same &= expect->tm_mday == time->tm_mday;
  37. same &= expect->tm_mon == time->tm_mon;
  38. same &= expect->tm_year == time->tm_year;
  39. if (!same && show) {
  40. show_time("expected", expect);
  41. show_time("actual", time);
  42. }
  43. return same ? 0 : -EINVAL;
  44. }
  45. /* Set and get the time */
  46. static int dm_test_rtc_set_get(struct unit_test_state *uts)
  47. {
  48. struct rtc_time now, time, cmp;
  49. struct udevice *dev, *emul;
  50. long offset, old_offset, old_base_time;
  51. ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
  52. ut_assertok(dm_rtc_get(dev, &now));
  53. ut_assertok(i2c_emul_find(dev, &emul));
  54. ut_assert(emul != NULL);
  55. /* Tell the RTC to go into manual mode */
  56. old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0);
  57. old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1);
  58. memset(&time, '\0', sizeof(time));
  59. time.tm_mday = 25;
  60. time.tm_mon = 8;
  61. time.tm_year = 2004;
  62. time.tm_sec = 0;
  63. time.tm_min = 18;
  64. time.tm_hour = 18;
  65. ut_assertok(dm_rtc_set(dev, &time));
  66. memset(&cmp, '\0', sizeof(cmp));
  67. ut_assertok(dm_rtc_get(dev, &cmp));
  68. ut_assertok(cmp_times(&time, &cmp, true));
  69. /* Increment by 1 second */
  70. offset = sandbox_i2c_rtc_set_offset(emul, false, 0);
  71. sandbox_i2c_rtc_set_offset(emul, false, offset + 1);
  72. memset(&cmp, '\0', sizeof(cmp));
  73. ut_assertok(dm_rtc_get(dev, &cmp));
  74. ut_asserteq(1, cmp.tm_sec);
  75. /* Check against original offset */
  76. sandbox_i2c_rtc_set_offset(emul, false, old_offset);
  77. ut_assertok(dm_rtc_get(dev, &cmp));
  78. ut_assertok(cmp_times(&now, &cmp, true));
  79. /* Back to the original offset */
  80. sandbox_i2c_rtc_set_offset(emul, false, 0);
  81. memset(&cmp, '\0', sizeof(cmp));
  82. ut_assertok(dm_rtc_get(dev, &cmp));
  83. ut_assertok(cmp_times(&now, &cmp, true));
  84. /* Increment the base time by 1 emul */
  85. sandbox_i2c_rtc_get_set_base_time(emul, old_base_time + 1);
  86. memset(&cmp, '\0', sizeof(cmp));
  87. ut_assertok(dm_rtc_get(dev, &cmp));
  88. if (now.tm_sec == 59) {
  89. ut_asserteq(0, cmp.tm_sec);
  90. } else {
  91. ut_asserteq(now.tm_sec + 1, cmp.tm_sec);
  92. }
  93. old_offset = sandbox_i2c_rtc_set_offset(emul, true, 0);
  94. return 0;
  95. }
  96. DM_TEST(dm_test_rtc_set_get, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
  97. /* Reset the time */
  98. static int dm_test_rtc_reset(struct unit_test_state *uts)
  99. {
  100. struct rtc_time now;
  101. struct udevice *dev, *emul;
  102. long old_base_time, base_time;
  103. ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
  104. ut_assertok(dm_rtc_get(dev, &now));
  105. ut_assertok(i2c_emul_find(dev, &emul));
  106. ut_assert(emul != NULL);
  107. old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, 0);
  108. ut_asserteq(0, sandbox_i2c_rtc_get_set_base_time(emul, -1));
  109. /* Resetting the RTC should put he base time back to normal */
  110. ut_assertok(dm_rtc_reset(dev));
  111. base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1);
  112. ut_asserteq(old_base_time, base_time);
  113. return 0;
  114. }
  115. DM_TEST(dm_test_rtc_reset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
  116. /* Check that two RTC devices can be used independently */
  117. static int dm_test_rtc_dual(struct unit_test_state *uts)
  118. {
  119. struct rtc_time now1, now2, cmp;
  120. struct udevice *dev1, *dev2;
  121. struct udevice *emul1, *emul2;
  122. long offset;
  123. ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev1));
  124. ut_assertok(dm_rtc_get(dev1, &now1));
  125. ut_assertok(uclass_get_device(UCLASS_RTC, 1, &dev2));
  126. ut_assertok(dm_rtc_get(dev2, &now2));
  127. ut_assertok(i2c_emul_find(dev1, &emul1));
  128. ut_assert(emul1 != NULL);
  129. ut_assertok(i2c_emul_find(dev2, &emul2));
  130. ut_assert(emul2 != NULL);
  131. offset = sandbox_i2c_rtc_set_offset(emul1, false, -1);
  132. sandbox_i2c_rtc_set_offset(emul2, false, offset + 1);
  133. memset(&cmp, '\0', sizeof(cmp));
  134. ut_assertok(dm_rtc_get(dev2, &cmp));
  135. ut_asserteq(-EINVAL, cmp_times(&now1, &cmp, false));
  136. memset(&cmp, '\0', sizeof(cmp));
  137. ut_assertok(dm_rtc_get(dev1, &cmp));
  138. ut_assertok(cmp_times(&now1, &cmp, true));
  139. return 0;
  140. }
  141. DM_TEST(dm_test_rtc_dual, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);