From 0f5d75e7521e34e4b2d0ff7c556a22175fd0e12a Mon Sep 17 00:00:00 2001 From: hanwckf Date: Thu, 21 Aug 2025 12:44:41 +0800 Subject: [PATCH] uboot-2025: add glbtn --- uboot-mtk-20250711/cmd/Kconfig | 6 ++ uboot-mtk-20250711/cmd/Makefile | 2 + uboot-mtk-20250711/cmd/glbtn.c | 110 +++++++++++++++++++++++++++++ uboot-mtk-20250711/cmd/led_blink.c | 100 ++++++++++++++++++++++++++ uboot-mtk-20250711/include/glbtn.h | 6 ++ 5 files changed, 224 insertions(+) create mode 100644 uboot-mtk-20250711/cmd/glbtn.c create mode 100644 uboot-mtk-20250711/cmd/led_blink.c create mode 100644 uboot-mtk-20250711/include/glbtn.h diff --git a/uboot-mtk-20250711/cmd/Kconfig b/uboot-mtk-20250711/cmd/Kconfig index c3689605c..c3dd1f767 100644 --- a/uboot-mtk-20250711/cmd/Kconfig +++ b/uboot-mtk-20250711/cmd/Kconfig @@ -3118,4 +3118,10 @@ config CMD_SPAWN_NUM_JOBS When a jobs exits, its identifier is available to be re-used by the next spawn command. +config CMD_GL_BTN + bool "GL-iNet button check command" + depends on BUTTON + default n + select POLLER + endif diff --git a/uboot-mtk-20250711/cmd/Makefile b/uboot-mtk-20250711/cmd/Makefile index 4566c47c4..eb94501b5 100644 --- a/uboot-mtk-20250711/cmd/Makefile +++ b/uboot-mtk-20250711/cmd/Makefile @@ -238,6 +238,8 @@ obj-$(CONFIG_CMD_AVB) += avb.o # Foundries.IO SCP03 obj-$(CONFIG_CMD_SCP03) += scp03.o +obj-$(CONFIG_CMD_GL_BTN) += glbtn.o led_blink.o + obj-$(CONFIG_HUSH_SELECTABLE) += cli.o obj-$(CONFIG_CMD_SPAWN) += spawn.o diff --git a/uboot-mtk-20250711/cmd/glbtn.c b/uboot-mtk-20250711/cmd/glbtn.c new file mode 100644 index 000000000..962c2c57e --- /dev/null +++ b/uboot-mtk-20250711/cmd/glbtn.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include +#include +#include + +static struct poller_async led_p; + +void led_control(const char *cmd, const char *name, const char *arg) +{ + const char *led = ofnode_conf_read_str(name); + char buf[128]; + + if (!led) + return; + + sprintf(buf, "%s %s %s", cmd, led, arg); + + run_command(buf, 0); +} + +static void gpio_power_clr(void) +{ + ofnode node = ofnode_path("/config"); + char cmd[128]; + const u32 *val; + int size, i; + + if (!ofnode_valid(node)) + return; + + val = ofnode_read_prop(node, "gpio_power_clr", &size); + if (!val) + return; + + for (i = 0; i < size / 4; i++) { + sprintf(cmd, "gpio clear %u", fdt32_to_cpu(val[i])); + run_command(cmd, 0); + } +} + +static void led_action_post(void *arg) +{ + led_control("ledblink", "blink_led", "0"); + led_control("led", "blink_led", "on"); +} + +static int do_glbtn(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + const char *button_label = NULL; + int ret, counter = 0; + struct udevice *dev; + ulong ts; + + led_control("ledblink", "blink_led", "250"); + + gpio_power_clr(); + + button_label = env_get("glbtn_key"); + if (!button_label) + button_label = "reset"; + + ret = button_get_by_label(button_label, &dev); + if (ret) { + printf("Button '%s' not found (err=%d)\n", button_label, ret); + return CMD_RET_FAILURE; + } + + if (!button_get_state(dev)) { + poller_async_register(&led_p, "led_pa"); + poller_call_async(&led_p, 1000000, led_action_post, NULL); + return CMD_RET_SUCCESS; + } + + led_control("ledblink", "blink_led", "500"); + + printf("RESET button is pressed for: %2d second(s)", counter++); + + ts = get_timer(0); + + while (button_get_state(dev) && counter < 4) { + if (get_timer(ts) < 1000) + continue; + + ts = get_timer(0); + + printf("\b\b\b\b\b\b\b\b\b\b\b\b%2d second(s)", counter++); + } + + printf("\n"); + + led_control("ledblink", "blink_led", "0"); + + if (counter == 4) { + led_control("led", "system_led", "on"); + run_command("httpd", 0); + } else { + led_control("ledblink", "blink_led", "0"); + } + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + glbtn, 1, 0, do_glbtn, + "GL-iNet button check", + "" +); diff --git a/uboot-mtk-20250711/cmd/led_blink.c b/uboot-mtk-20250711/cmd/led_blink.c new file mode 100644 index 000000000..cc5c6a3b6 --- /dev/null +++ b/uboot-mtk-20250711/cmd/led_blink.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include + +#define MAX_LED_BLINK 5 + +struct led_blink { + struct udevice *dev; + int freq_ms; + uint64_t next_event; +}; + +static struct led_blink led_blinks[MAX_LED_BLINK]; + +static void led_blink_func(struct poller_struct *poller) +{ + uint64_t now = timer_get_us() / 1000; + int i; + + for (i = 0; i < MAX_LED_BLINK; i++) { + struct led_blink *led = &led_blinks[i]; + if (!led->dev) + continue; + + if (led->next_event && now < led->next_event) + continue; + + led_set_state(led->dev, LEDST_TOGGLE); + + led->next_event = now + led->freq_ms; + } +} + +static struct poller_struct led_poller = { + .func = led_blink_func, +}; + +static int do_led_blink(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + struct led_blink *led = NULL; + struct udevice *dev; + const char *label; + int freq_ms = 0; + int i, ret; + + if (argc < 3) + return CMD_RET_USAGE; + + label = argv[1]; + freq_ms = dectoul(argv[2], NULL); + + ret = led_get_by_label(label, &dev); + if (ret) { + printf("LED '%s' not found (err=%d)\n", label, ret); + return CMD_RET_FAILURE; + } + + for (i = 0; i < MAX_LED_BLINK; i++) { + if (led_blinks[i].dev == dev) { + led = &led_blinks[i]; + break; + } + } + + if (freq_ms < 1) { + led->dev = NULL; + led_set_state(dev, LEDST_OFF); + return 0; + } + + if (!led) { + for (i = 0; i < MAX_LED_BLINK; i++) { + if (!led_blinks[i].dev) { + led = &led_blinks[i]; + led->dev = dev; + break; + } + } + } + + if (!led) + return CMD_RET_FAILURE; + + led_set_state(dev, LEDST_TOGGLE); + + led->freq_ms = freq_ms; + + poller_register(&led_poller, "led"); + + return 0; +} + +U_BOOT_CMD( + ledblink, 3, 0, do_led_blink, + "led blink", + " [blink-freq in ms]" +); diff --git a/uboot-mtk-20250711/include/glbtn.h b/uboot-mtk-20250711/include/glbtn.h new file mode 100644 index 000000000..70c79068d --- /dev/null +++ b/uboot-mtk-20250711/include/glbtn.h @@ -0,0 +1,6 @@ +#ifndef _GLBTN_H_ +#define _GLBTN_H_ + +void led_control(const char *cmd, const char *name, const char *arg); + +#endif