// SPDX-License-Identifier: GPL-2.0+ #include #include #include #include #include #include #include #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 = simple_strtoul(argv[0], NULL, 16); len = simple_strtoul(argv[1], NULL, 16); if (argc == 3) { u8 *addr; addr = map_sysmem(simple_strtoul(argv[2], NULL, 16), 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 = simple_strtoul(argv[0], NULL, 16); if (argc == 3) { u8 *addr; len = simple_strtoul(argv[1], NULL, 16); addr = map_sysmem(simple_strtoul(argv[2], NULL, 16), 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 = simple_strtoul(argv[1], NULL, 10); 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 - read and display 8-bit registers starting at \n" "rtc read - read 8-bit registers starting at to memory \n" "rtc write - write 8-bit registers starting at \n" "rtc write - write from memory to 8-bit registers starting at \n" );