rtc.c 4.8 KB

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