rtc.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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 <console.h>
  8. #include <dm.h>
  9. #include <i2c.h>
  10. #include <log.h>
  11. #include <rtc.h>
  12. #include <asm/io.h>
  13. #include <asm/rtc.h>
  14. #include <asm/test.h>
  15. #include <dm/test.h>
  16. #include <test/test.h>
  17. #include <test/ut.h>
  18. /* Simple RTC sanity check */
  19. static int dm_test_rtc_base(struct unit_test_state *uts)
  20. {
  21. struct udevice *dev;
  22. ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_RTC, 2, &dev));
  23. ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
  24. ut_assertok(uclass_get_device(UCLASS_RTC, 1, &dev));
  25. return 0;
  26. }
  27. DM_TEST(dm_test_rtc_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  28. static void show_time(const char *msg, struct rtc_time *time)
  29. {
  30. printf("%s: %02d/%02d/%04d %02d:%02d:%02d\n", msg,
  31. time->tm_mday, time->tm_mon, time->tm_year,
  32. time->tm_hour, time->tm_min, time->tm_sec);
  33. }
  34. static int cmp_times(struct rtc_time *expect, struct rtc_time *time, bool show)
  35. {
  36. bool same;
  37. same = expect->tm_sec == time->tm_sec;
  38. same &= expect->tm_min == time->tm_min;
  39. same &= expect->tm_hour == time->tm_hour;
  40. same &= expect->tm_mday == time->tm_mday;
  41. same &= expect->tm_mon == time->tm_mon;
  42. same &= expect->tm_year == time->tm_year;
  43. if (!same && show) {
  44. show_time("expected", expect);
  45. show_time("actual", time);
  46. }
  47. return same ? 0 : -EINVAL;
  48. }
  49. /* Set and get the time */
  50. static int dm_test_rtc_set_get(struct unit_test_state *uts)
  51. {
  52. struct rtc_time now, time, cmp;
  53. struct udevice *dev, *emul;
  54. long offset, old_offset, old_base_time;
  55. ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
  56. ut_assertok(dm_rtc_get(dev, &now));
  57. ut_assertok(i2c_emul_find(dev, &emul));
  58. ut_assert(emul != NULL);
  59. /* Tell the RTC to go into manual mode */
  60. old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0);
  61. old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1);
  62. memset(&time, '\0', sizeof(time));
  63. time.tm_mday = 3;
  64. time.tm_mon = 6;
  65. time.tm_year = 2004;
  66. time.tm_sec = 0;
  67. time.tm_min = 18;
  68. time.tm_hour = 18;
  69. ut_assertok(dm_rtc_set(dev, &time));
  70. memset(&cmp, '\0', sizeof(cmp));
  71. ut_assertok(dm_rtc_get(dev, &cmp));
  72. ut_assertok(cmp_times(&time, &cmp, true));
  73. memset(&time, '\0', sizeof(time));
  74. time.tm_mday = 31;
  75. time.tm_mon = 8;
  76. time.tm_year = 2004;
  77. time.tm_sec = 0;
  78. time.tm_min = 18;
  79. time.tm_hour = 18;
  80. ut_assertok(dm_rtc_set(dev, &time));
  81. memset(&cmp, '\0', sizeof(cmp));
  82. ut_assertok(dm_rtc_get(dev, &cmp));
  83. ut_assertok(cmp_times(&time, &cmp, true));
  84. /* Increment by 1 second */
  85. offset = sandbox_i2c_rtc_set_offset(emul, false, 0);
  86. sandbox_i2c_rtc_set_offset(emul, false, offset + 1);
  87. memset(&cmp, '\0', sizeof(cmp));
  88. ut_assertok(dm_rtc_get(dev, &cmp));
  89. ut_asserteq(1, cmp.tm_sec);
  90. /* Check against original offset */
  91. sandbox_i2c_rtc_set_offset(emul, false, old_offset);
  92. ut_assertok(dm_rtc_get(dev, &cmp));
  93. ut_assertok(cmp_times(&now, &cmp, true));
  94. /* Back to the original offset */
  95. sandbox_i2c_rtc_set_offset(emul, false, 0);
  96. memset(&cmp, '\0', sizeof(cmp));
  97. ut_assertok(dm_rtc_get(dev, &cmp));
  98. ut_assertok(cmp_times(&now, &cmp, true));
  99. /* Increment the base time by 1 emul */
  100. sandbox_i2c_rtc_get_set_base_time(emul, old_base_time + 1);
  101. memset(&cmp, '\0', sizeof(cmp));
  102. ut_assertok(dm_rtc_get(dev, &cmp));
  103. if (now.tm_sec == 59) {
  104. ut_asserteq(0, cmp.tm_sec);
  105. } else {
  106. ut_asserteq(now.tm_sec + 1, cmp.tm_sec);
  107. }
  108. old_offset = sandbox_i2c_rtc_set_offset(emul, true, 0);
  109. return 0;
  110. }
  111. DM_TEST(dm_test_rtc_set_get, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  112. static int dm_test_rtc_read_write(struct unit_test_state *uts)
  113. {
  114. struct rtc_time time;
  115. struct udevice *dev, *emul;
  116. long old_offset;
  117. u8 buf[4], reg;
  118. ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
  119. memcpy(buf, "car", 4);
  120. ut_assertok(dm_rtc_write(dev, REG_AUX0, buf, 4));
  121. memset(buf, '\0', sizeof(buf));
  122. ut_assertok(dm_rtc_read(dev, REG_AUX0, buf, 4));
  123. ut_asserteq(memcmp(buf, "car", 4), 0);
  124. reg = 'b';
  125. ut_assertok(dm_rtc_write(dev, REG_AUX0, &reg, 1));
  126. memset(buf, '\0', sizeof(buf));
  127. ut_assertok(dm_rtc_read(dev, REG_AUX0, buf, 4));
  128. ut_asserteq(memcmp(buf, "bar", 4), 0);
  129. reg = 't';
  130. ut_assertok(dm_rtc_write(dev, REG_AUX2, &reg, 1));
  131. memset(buf, '\0', sizeof(buf));
  132. ut_assertok(dm_rtc_read(dev, REG_AUX1, buf, 3));
  133. ut_asserteq(memcmp(buf, "at", 3), 0);
  134. ut_assertok(i2c_emul_find(dev, &emul));
  135. ut_assert(emul != NULL);
  136. old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0);
  137. ut_assertok(dm_rtc_get(dev, &time));
  138. ut_assertok(dm_rtc_read(dev, REG_SEC, &reg, 1));
  139. ut_asserteq(time.tm_sec, reg);
  140. ut_assertok(dm_rtc_read(dev, REG_MDAY, &reg, 1));
  141. ut_asserteq(time.tm_mday, reg);
  142. sandbox_i2c_rtc_set_offset(emul, true, old_offset);
  143. return 0;
  144. }
  145. DM_TEST(dm_test_rtc_read_write, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  146. /* Test 'rtc list' command */
  147. static int dm_test_rtc_cmd_list(struct unit_test_state *uts)
  148. {
  149. console_record_reset();
  150. run_command("rtc list", 0);
  151. ut_assert_nextline("RTC #0 - rtc@43");
  152. ut_assert_nextline("RTC #1 - rtc@61");
  153. ut_assert_console_end();
  154. return 0;
  155. }
  156. DM_TEST(dm_test_rtc_cmd_list, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  157. /* Test 'rtc read' and 'rtc write' commands */
  158. static int dm_test_rtc_cmd_rw(struct unit_test_state *uts)
  159. {
  160. console_record_reset();
  161. run_command("rtc dev 0", 0);
  162. ut_assert_nextline("RTC #0 - rtc@43");
  163. ut_assert_console_end();
  164. run_command("rtc write 0x30 aabb", 0);
  165. ut_assert_console_end();
  166. run_command("rtc read 0x30 2", 0);
  167. ut_assert_nextline("00000030: aa bb ..");
  168. ut_assert_console_end();
  169. run_command("rtc dev 1", 0);
  170. ut_assert_nextline("RTC #1 - rtc@61");
  171. ut_assert_console_end();
  172. run_command("rtc write 0x30 ccdd", 0);
  173. ut_assert_console_end();
  174. run_command("rtc read 0x30 2", 0);
  175. ut_assert_nextline("00000030: cc dd ..");
  176. ut_assert_console_end();
  177. /*
  178. * Switch back to device #0, check that its aux registers
  179. * still have the same values.
  180. */
  181. run_command("rtc dev 0", 0);
  182. ut_assert_nextline("RTC #0 - rtc@43");
  183. ut_assert_console_end();
  184. run_command("rtc read 0x30 2", 0);
  185. ut_assert_nextline("00000030: aa bb ..");
  186. ut_assert_console_end();
  187. return 0;
  188. }
  189. DM_TEST(dm_test_rtc_cmd_rw, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  190. /* Reset the time */
  191. static int dm_test_rtc_reset(struct unit_test_state *uts)
  192. {
  193. struct rtc_time now;
  194. struct udevice *dev, *emul;
  195. long old_base_time, base_time;
  196. ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
  197. ut_assertok(dm_rtc_get(dev, &now));
  198. ut_assertok(i2c_emul_find(dev, &emul));
  199. ut_assert(emul != NULL);
  200. old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, 0);
  201. ut_asserteq(0, sandbox_i2c_rtc_get_set_base_time(emul, -1));
  202. /* Resetting the RTC should put he base time back to normal */
  203. ut_assertok(dm_rtc_reset(dev));
  204. base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1);
  205. ut_asserteq(old_base_time, base_time);
  206. return 0;
  207. }
  208. DM_TEST(dm_test_rtc_reset, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  209. /* Check that two RTC devices can be used independently */
  210. static int dm_test_rtc_dual(struct unit_test_state *uts)
  211. {
  212. struct rtc_time now1, now2, cmp;
  213. struct udevice *dev1, *dev2;
  214. struct udevice *emul1, *emul2;
  215. long offset;
  216. ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev1));
  217. ut_assertok(dm_rtc_get(dev1, &now1));
  218. ut_assertok(uclass_get_device(UCLASS_RTC, 1, &dev2));
  219. ut_assertok(dm_rtc_get(dev2, &now2));
  220. ut_assertok(i2c_emul_find(dev1, &emul1));
  221. ut_assert(emul1 != NULL);
  222. ut_assertok(i2c_emul_find(dev2, &emul2));
  223. ut_assert(emul2 != NULL);
  224. offset = sandbox_i2c_rtc_set_offset(emul1, false, -1);
  225. sandbox_i2c_rtc_set_offset(emul2, false, offset + 1);
  226. memset(&cmp, '\0', sizeof(cmp));
  227. ut_assertok(dm_rtc_get(dev2, &cmp));
  228. ut_asserteq(-EINVAL, cmp_times(&now1, &cmp, false));
  229. memset(&cmp, '\0', sizeof(cmp));
  230. ut_assertok(dm_rtc_get(dev1, &cmp));
  231. ut_assertok(cmp_times(&now1, &cmp, true));
  232. return 0;
  233. }
  234. DM_TEST(dm_test_rtc_dual, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);