mirror of
https://github.com/u-boot/u-boot.git
synced 2024-12-11 13:43:27 +08:00
d47e1fa819
Add a test for the button_cmd feature. This validates that commands can
be mapped to two buttons, that the correct command runs based on which
button is pressed, that only 1 command is run, and that no command runs
if button_cmd_0_name is wrong or unset.
Additionally, fix a potential uninitialised variable use caught by these
tests, the btn variable in get_button_cmd() is assumed to be null if
button_get_by_label() fails, but it's actually used uninitialised in
that case.
CONFIG_BUTTON is now enabled automatically and was removed when running
save_defconfig.
Fixes: e761035b64
("boot: add support for button commands")
Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
84 lines
1.8 KiB
C
84 lines
1.8 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Copyright (c) 2023 Linaro Ltd.
|
|
* Author: Caleb Connolly <caleb.connolly@linaro.org>
|
|
*/
|
|
|
|
#include <button.h>
|
|
#include <command.h>
|
|
#include <env.h>
|
|
#include <log.h>
|
|
#include <vsprintf.h>
|
|
|
|
/* Some sane limit "just in case" */
|
|
#define MAX_BTN_CMDS 32
|
|
|
|
struct button_cmd {
|
|
bool pressed;
|
|
const char *btn_name;
|
|
const char *cmd;
|
|
};
|
|
|
|
/*
|
|
* Button commands are set via environment variables, e.g.:
|
|
* button_cmd_N_name=Volume Up
|
|
* button_cmd_N=fastboot usb 0
|
|
*
|
|
* This function will retrieve the command for the given button N
|
|
* and populate the cmd struct with the command string and pressed
|
|
* state of the button.
|
|
*
|
|
* Returns 1 if a command was found, 0 otherwise.
|
|
*/
|
|
static int get_button_cmd(int n, struct button_cmd *cmd)
|
|
{
|
|
const char *cmd_str;
|
|
struct udevice *btn = NULL;
|
|
char buf[24];
|
|
|
|
snprintf(buf, sizeof(buf), "button_cmd_%d_name", n);
|
|
cmd->btn_name = env_get(buf);
|
|
if (!cmd->btn_name)
|
|
return 0;
|
|
|
|
button_get_by_label(cmd->btn_name, &btn);
|
|
if (!btn) {
|
|
log_err("No button labelled '%s'\n", cmd->btn_name);
|
|
return 0;
|
|
}
|
|
|
|
cmd->pressed = button_get_state(btn) == BUTTON_ON;
|
|
/* If the button isn't pressed then cmd->cmd will be unused so don't waste
|
|
* cycles reading it
|
|
*/
|
|
if (!cmd->pressed)
|
|
return 1;
|
|
|
|
snprintf(buf, sizeof(buf), "button_cmd_%d", n);
|
|
cmd_str = env_get(buf);
|
|
if (!cmd_str) {
|
|
log_err("No command set for button '%s'\n", cmd->btn_name);
|
|
return 0;
|
|
}
|
|
|
|
cmd->cmd = cmd_str;
|
|
|
|
return 1;
|
|
}
|
|
|
|
void process_button_cmds(void)
|
|
{
|
|
struct button_cmd cmd = {0};
|
|
int i = 0;
|
|
|
|
while (get_button_cmd(i++, &cmd) && i < MAX_BTN_CMDS) {
|
|
if (!cmd.pressed)
|
|
continue;
|
|
|
|
log_info("BTN '%s'> %s\n", cmd.btn_name, cmd.cmd);
|
|
run_command(cmd.cmd, CMD_FLAG_ENV);
|
|
/* Don't run commands for multiple buttons */
|
|
return;
|
|
}
|
|
}
|