From: Petr Hodina <[email protected]> 'button list' prints state once and exits. The new subcommand 'monitor' loops the input states with default timeout 5s so live verification on the device is easier.
Signed-off-by: Petr Hodina <[email protected]> --- cmd/button.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 95 insertions(+), 9 deletions(-) diff --git a/cmd/button.c b/cmd/button.c index 3e6db3f5b8e..268f5a64952 100644 --- a/cmd/button.c +++ b/cmd/button.c @@ -7,8 +7,14 @@ #include <command.h> #include <dm.h> +#include <ansi.h> #include <button.h> +#include <console.h> +#include <stdio.h> +#include <time.h> +#include <vsprintf.h> #include <dm/uclass-internal.h> +#include <linux/delay.h> static const char *const state_label[] = { [BUTTON_OFF] = "off", @@ -28,10 +34,27 @@ static int show_button_state(struct udevice *dev) return ret; } +static void show_button_status(struct udevice *dev) +{ + int ret; + + if (!device_active(dev)) { + puts("<inactive>"); + return; + } + + ret = button_get_state(dev); + if (ret >= BUTTON_COUNT) + ret = -EINVAL; + if (ret >= 0) + puts(state_label[ret]); + else + printf("Error %d", ret); +} + static int list_buttons(void) { struct udevice *dev; - int ret; for (uclass_find_first_device(UCLASS_BUTTON, &dev); dev; @@ -41,13 +64,62 @@ static int list_buttons(void) if (!plat->label) continue; printf("%-15s ", plat->label); - if (device_active(dev)) { - ret = show_button_state(dev); - if (ret < 0) - printf("Error %d\n", ret); - } else { - printf("<inactive>\n"); + show_button_status(dev); + puts("\n"); + } + + return 0; +} + +static int monitor_buttons(unsigned long timeout_ms) +{ + ulong start = get_timer(0); + ulong elapsed; + int ret; + + /* Probe once; buttons which fail to probe are shown as <inactive> */ + ret = uclass_probe_all(UCLASS_BUTTON); + + puts(ANSI_CLEAR_CONSOLE); + printf(ANSI_CURSOR_POSITION, 1, 1); + puts("Button monitor\n"); + if (ret) + printf("Some buttons failed to probe (err=%d)", ret); + puts("\n"); + + for (;;) { + struct udevice *dev; + + if (ctrlc()) + break; + + elapsed = get_timer(start); + if (timeout_ms && elapsed >= timeout_ms) + break; + + printf(ANSI_CURSOR_POSITION, 3, 1); + if (timeout_ms) + printf("%lu.%lus left, Ctrl-C to quit" + ANSI_CLEAR_LINE_TO_END "\n", + (timeout_ms - elapsed) / 1000, + ((timeout_ms - elapsed) % 1000) / 100); + else + puts("Ctrl-C to quit" ANSI_CLEAR_LINE_TO_END "\n"); + puts("--------------------\n"); + + for (uclass_find_first_device(UCLASS_BUTTON, &dev); + dev; + uclass_find_next_device(&dev)) { + struct button_uc_plat *plat = dev_get_uclass_plat(dev); + + if (!plat->label) + continue; + printf("%-15s ", plat->label); + show_button_status(dev); + puts(ANSI_CLEAR_LINE_TO_END "\n"); } + + mdelay(100); } return 0; @@ -65,6 +137,17 @@ int do_button(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) button_label = argv[1]; if (strncmp(button_label, "list", 4) == 0) return list_buttons(); + if (strcmp(button_label, "monitor") == 0) { + unsigned long timeout_ms = 5000; + char *endp; + + if (argc >= 3) { + timeout_ms = dectoul(argv[2], &endp); + if (endp == argv[2] || *endp) + return CMD_RET_USAGE; + } + return monitor_buttons(timeout_ms); + } ret = button_get_by_label(button_label, &dev); if (ret) { @@ -78,8 +161,11 @@ int do_button(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) } U_BOOT_CMD( - button, 2, 1, do_button, + button, 3, 1, do_button, "manage buttons", "<button_label> \tGet button state\n" - "button list\t\tShow a list of buttons" + "button list\t\tShow a list of buttons\n" + "button monitor [timeout_ms]\tLive table, updates every 100ms,\n" + " \tquits on timeout (default 5000ms,\n" + " \t0 = until Ctrl-C) or Ctrl-C" ); -- 2.55.0
