rtc.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // SPDX-License-Identifier: GPL-2.0+
  2. #include <common.h>
  3. #include <command.h>
  4. #include <display_options.h>
  5. #include <dm.h>
  6. #include <hexdump.h>
  7. #include <i2c.h>
  8. #include <mapmem.h>
  9. #include <rtc.h>
  10. #define MAX_RTC_BYTES 32
  11. static int do_rtc_read(struct udevice *dev, int argc, char * const argv[])
  12. {
  13. u8 buf[MAX_RTC_BYTES];
  14. int reg, len, ret, r;
  15. if (argc < 2 || argc > 3)
  16. return CMD_RET_USAGE;
  17. reg = hextoul(argv[0], NULL);
  18. len = hextoul(argv[1], NULL);
  19. if (argc == 3) {
  20. u8 *addr;
  21. addr = map_sysmem(hextoul(argv[2], NULL), len);
  22. ret = dm_rtc_read(dev, reg, addr, len);
  23. unmap_sysmem(addr);
  24. if (ret) {
  25. printf("dm_rtc_read() failed: %d\n", ret);
  26. return CMD_RET_FAILURE;
  27. }
  28. return CMD_RET_SUCCESS;
  29. }
  30. while (len) {
  31. r = min_t(int, len, sizeof(buf));
  32. ret = dm_rtc_read(dev, reg, buf, r);
  33. if (ret) {
  34. printf("dm_rtc_read() failed: %d\n", ret);
  35. return CMD_RET_FAILURE;
  36. }
  37. print_buffer(reg, buf, 1, r, 0);
  38. len -= r;
  39. reg += r;
  40. }
  41. return CMD_RET_SUCCESS;
  42. }
  43. static int do_rtc_write(struct udevice *dev, int argc, char * const argv[])
  44. {
  45. u8 buf[MAX_RTC_BYTES];
  46. int reg, len, ret;
  47. const char *s;
  48. int slen;
  49. if (argc < 2 || argc > 3)
  50. return CMD_RET_USAGE;
  51. reg = hextoul(argv[0], NULL);
  52. if (argc == 3) {
  53. u8 *addr;
  54. len = hextoul(argv[1], NULL);
  55. addr = map_sysmem(hextoul(argv[2], NULL), len);
  56. ret = dm_rtc_write(dev, reg, addr, len);
  57. unmap_sysmem(addr);
  58. if (ret) {
  59. printf("dm_rtc_write() failed: %d\n", ret);
  60. return CMD_RET_FAILURE;
  61. }
  62. return CMD_RET_SUCCESS;
  63. }
  64. s = argv[1];
  65. slen = strlen(s);
  66. if (slen % 2) {
  67. printf("invalid hex string\n");
  68. return CMD_RET_FAILURE;
  69. }
  70. while (slen) {
  71. len = min_t(int, slen / 2, sizeof(buf));
  72. if (hex2bin(buf, s, len)) {
  73. printf("invalid hex string\n");
  74. return CMD_RET_FAILURE;
  75. }
  76. ret = dm_rtc_write(dev, reg, buf, len);
  77. if (ret) {
  78. printf("dm_rtc_write() failed: %d\n", ret);
  79. return CMD_RET_FAILURE;
  80. }
  81. s += 2 * len;
  82. slen -= 2 * len;
  83. }
  84. return CMD_RET_SUCCESS;
  85. }
  86. int do_rtc(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
  87. {
  88. static int curr_rtc;
  89. struct udevice *dev;
  90. int ret, idx;
  91. if (argc < 2)
  92. return CMD_RET_USAGE;
  93. argc--;
  94. argv++;
  95. if (!strcmp(argv[0], "list")) {
  96. struct uclass *uc;
  97. idx = 0;
  98. uclass_id_foreach_dev(UCLASS_RTC, dev, uc) {
  99. printf("RTC #%d - %s\n", idx++, dev->name);
  100. }
  101. if (!idx) {
  102. printf("*** no RTC devices available ***\n");
  103. return CMD_RET_FAILURE;
  104. }
  105. return CMD_RET_SUCCESS;
  106. }
  107. idx = curr_rtc;
  108. if (!strcmp(argv[0], "dev") && argc >= 2)
  109. idx = dectoul(argv[1], NULL);
  110. ret = uclass_get_device(UCLASS_RTC, idx, &dev);
  111. if (ret) {
  112. printf("Cannot find RTC #%d: err=%d\n", idx, ret);
  113. return CMD_RET_FAILURE;
  114. }
  115. if (!strcmp(argv[0], "dev")) {
  116. /* Show the existing or newly selected RTC */
  117. if (argc >= 2)
  118. curr_rtc = idx;
  119. printf("RTC #%d - %s\n", idx, dev->name);
  120. return CMD_RET_SUCCESS;
  121. }
  122. if (!strcmp(argv[0], "read"))
  123. return do_rtc_read(dev, argc - 1, argv + 1);
  124. if (!strcmp(argv[0], "write"))
  125. return do_rtc_write(dev, argc - 1, argv + 1);
  126. return CMD_RET_USAGE;
  127. }
  128. U_BOOT_CMD(
  129. rtc, 5, 0, do_rtc,
  130. "RTC subsystem",
  131. "list - show available rtc devices\n"
  132. "rtc dev [n] - show or set current rtc device\n"
  133. "rtc read <reg> <count> - read and display 8-bit registers starting at <reg>\n"
  134. "rtc read <reg> <count> <addr> - read 8-bit registers starting at <reg> to memory <addr>\n"
  135. "rtc write <reg> <hexstring> - write 8-bit registers starting at <reg>\n"
  136. "rtc write <reg> <count> <addr> - write from memory <addr> to 8-bit registers starting at <reg>\n"
  137. );