1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2023 Linaro Ltd. 4 * Author: Caleb Connolly <caleb.connolly@linaro.org> 5 */ 6 7#include <button.h> 8#include <command.h> 9#include <env.h> 10#include <log.h> 11#include <vsprintf.h> 12 13/* Some sane limit "just in case" */ 14#define MAX_BTN_CMDS 32 15 16struct button_cmd { 17 bool pressed; 18 const char *btn_name; 19 const char *cmd; 20}; 21 22/* 23 * Button commands are set via environment variables, e.g.: 24 * button_cmd_N_name=Volume Up 25 * button_cmd_N=fastboot usb 0 26 * 27 * This function will retrieve the command for the given button N 28 * and populate the cmd struct with the command string and pressed 29 * state of the button. 30 * 31 * Returns 1 if a command was found, 0 otherwise. 32 */ 33static int get_button_cmd(int n, struct button_cmd *cmd) 34{ 35 const char *cmd_str; 36 struct udevice *btn = NULL; 37 char buf[24]; 38 39 snprintf(buf, sizeof(buf), "button_cmd_%d_name", n); 40 cmd->btn_name = env_get(buf); 41 if (!cmd->btn_name) 42 return 0; 43 44 button_get_by_label(cmd->btn_name, &btn); 45 if (!btn) { 46 log_err("No button labelled '%s'\n", cmd->btn_name); 47 return 0; 48 } 49 50 cmd->pressed = button_get_state(btn) == BUTTON_ON; 51 /* If the button isn't pressed then cmd->cmd will be unused so don't waste 52 * cycles reading it 53 */ 54 if (!cmd->pressed) 55 return 1; 56 57 snprintf(buf, sizeof(buf), "button_cmd_%d", n); 58 cmd_str = env_get(buf); 59 if (!cmd_str) { 60 log_err("No command set for button '%s'\n", cmd->btn_name); 61 return 0; 62 } 63 64 cmd->cmd = cmd_str; 65 66 return 1; 67} 68 69void process_button_cmds(void) 70{ 71 struct button_cmd cmd = {0}; 72 int i = 0; 73 74 while (get_button_cmd(i++, &cmd) && i < MAX_BTN_CMDS) { 75 if (!cmd.pressed) 76 continue; 77 78 log_info("BTN '%s'> %s\n", cmd.btn_name, cmd.cmd); 79 run_command(cmd.cmd, CMD_FLAG_ENV); 80 /* Don't run commands for multiple buttons */ 81 return; 82 } 83} 84