blob: b6a8434d6f29258ea75f5891bee93ca2310782c7 [file] [log] [blame]
Caleb Connolly2259c292024-01-09 11:51:09 +00001// 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;
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}