From: Petr Hodina <[email protected]> Add CONFIG_CMD_PHONEMENU for cmd/phone_util.c which adds two commands to be used as menu actions:
- qcom_poweroff: power off via PSCI SYSTEM_OFF - usbether: bind and probe the USB Ethernet (RNDIS) gadget on demand - dfu_pwr command which handles power button press to exit the DFU mode without board reboot Signed-off-by: Petr Hodina <[email protected]> --- MAINTAINERS | 1 + cmd/Kconfig | 11 ++++++ cmd/Makefile | 1 + cmd/phone_util.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 45e9076de67..4b0b0b2f3a5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -687,6 +687,7 @@ R: Sumit Garg <[email protected]> L: [email protected] S: Maintained T: git https://source.denx.de/u-boot/custodians/u-boot-snapdragon.git +F: cmd/phone_util.c F: configs/qcm6490_defconfig F: configs/qcs9100_defconfig F: drivers/*/*/pm8???-* diff --git a/cmd/Kconfig b/cmd/Kconfig index c71c6824a19..09dbf73afdc 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -521,6 +521,17 @@ config CMD_BOOTMENU help Add an ANSI terminal boot menu command. +config CMD_PHONEMENU + bool "Boot menu for devices with high resolution display" + depends on VIDEO && ARM + select MENU + select CMD_BOOTMENU + help + ANSI-styled boot menu laid out in labelled sections, intended for + devices with high resolution displays. Navigation reuses the bootmenu + key handler, so volume up/down and power work through + BUTTON_REMAP_PHONE_KEYS. + config CMD_ADTIMG bool "adtimg" help diff --git a/cmd/Makefile b/cmd/Makefile index bbbdfcc4ded..762572156cd 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_CMD_BMP) += bmp.o obj-$(CONFIG_CMD_BOOTCOUNT) += bootcount.o obj-$(CONFIG_CMD_BOOTEFI) += bootefi.o obj-$(CONFIG_CMD_BOOTMENU) += bootmenu.o +obj-$(CONFIG_CMD_PHONEMENU) += phone_util.o obj-$(CONFIG_CMD_BOOTSTAGE) += bootstage.o obj-$(CONFIG_CMD_BOOTZ) += bootz.o obj-$(CONFIG_CMD_BOOTI) += booti.o diff --git a/cmd/phone_util.c b/cmd/phone_util.c new file mode 100644 index 00000000000..1389b2ca6cd --- /dev/null +++ b/cmd/phone_util.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include <button.h> +#include <command.h> +#include <cyclic.h> +#include <dfu.h> +#include <g_dnl.h> +#include <net-common.h> +#include <stdio.h> +#include <asm/system.h> +#include <linux/delay.h> + +#if CONFIG_IS_ENABLED(USB_ETHER) +static int do_usbether(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret = usb_ether_init(); + + if (ret < 0) { + printf("usb_ether init failed: %d\n", ret); + return CMD_RET_FAILURE; + } + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(usbether, 1, 0, do_usbether, + "start USB Ethernet (RNDIS) gadget for tftp/pxe boot", + "\n" + " - Bind the USB Ethernet gadget driver. After running, set"); +#endif + +static int do_phone_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + if (!CONFIG_IS_ENABLED(PSCI_RESET)) { + printf("PSCI not enabled on this board - cannot power off\n"); + return CMD_RET_FAILURE; + } + + puts("\nPowering off via PSCI SYSTEM_OFF\n"); + mdelay(50); + psci_system_off(); + return CMD_RET_FAILURE; +} + +U_BOOT_CMD(phone_poweroff, 1, 0, do_phone_poweroff, + "power off the device via PSCI SYSTEM_OFF", + "\n" + " - Invoke PSCI 0.2 SYSTEM_OFF. TZ handles the PMIC sequencing"); + +#if CONFIG_IS_ENABLED(CMD_DFU) +/* + * DFU with a power-button exit. The stock DFU loop in common/dfu.c polls + * g_dnl_detach() and ctrlc() on every iteration so a call to + * g_dnl_trigger_detach() will return us back to the menu. + */ +static bool dfu_pwr_pressed; +static bool dfu_pwr_exit_requested; +static struct udevice *dfu_pwr_btn; +static struct cyclic_info dfu_pwr_cyc; + +bool dfu_usb_get_reset(void) +{ + return !dfu_pwr_exit_requested; +} + +static void dfu_pwr_poll(struct cyclic_info *c) +{ + if (dfu_pwr_pressed) + return; + if (button_get_state(dfu_pwr_btn) == BUTTON_ON) { + dfu_pwr_pressed = true; + dfu_pwr_exit_requested = true; + g_dnl_trigger_detach(); + } +} + +static int do_dfu_pwr(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + + ret = button_get_by_label("Power Button", &dfu_pwr_btn); + if (ret) { + printf("Power Button not found (err=%d)\n", ret); + return CMD_RET_FAILURE; + } + + puts("\nDFU mode active. Press the power button to exit.\n"); + + dfu_pwr_pressed = false; + dfu_pwr_exit_requested = false; + cyclic_register(&dfu_pwr_cyc, dfu_pwr_poll, + 50 * 1000, "dfu_pwr_exit"); + + ret = run_command("run dfu", 0); + + cyclic_unregister(&dfu_pwr_cyc); + + /* Debounce release so the press doesn't cascade into the menu. */ + while (button_get_state(dfu_pwr_btn) == BUTTON_ON) + mdelay(20); + + return ret; +} + +U_BOOT_CMD(dfu_pwr, 1, 0, do_dfu_pwr, + "enter DFU mode; exit on power-button press", + "\n" + " - Run the `dfu` env alias with a cyclic that triggers a\n" + " gadget detach when the power button is pressed."); +#endif /* CMD_DFU */ -- 2.55.0
