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