diff options
author | Diego Rondini <diego.rondini@kynetics.com> | 2022-03-22 18:14:35 +0100 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-04-08 15:27:57 -0400 |
commit | e4c83ab5bc1da4eacc7309a902121b14d3c1e9c3 (patch) | |
tree | 635b782d834e624d0b23b6ce2760d64e53bda8cf | |
parent | bd2a6164776de45eb1cf9bfbd6f3d0558b046c41 (diff) | |
download | u-boot-WIP/2022-04-08-gpio-updates.zip u-boot-WIP/2022-04-08-gpio-updates.tar.gz u-boot-WIP/2022-04-08-gpio-updates.tar.bz2 |
cmd: gpio: Add `gpio read` subcommandWIP/2022-04-08-gpio-updates
As explained in commit 4af2a33ee5b9 ("cmd: gpio: Make `gpio input`
return pin value again") the `gpio input` is used in scripts to obtain
the value of a pin, despite the fact that CMD_RET_FAILURE is
indistinguishable from a valid pin value.
To be able to detect failures and properly use the value of a GPIO in
scripts we introduce the `gpio read` command that sets the variable
`name` to the value of the pin. Return code of the `gpio read` command
can be used to check for CMD_RET_SUCCESS or CMD_RET_FAILURE.
Signed-off-by: Diego Rondini <diego.rondini@kynetics.com>
-rw-r--r-- | cmd/gpio.c | 24 | ||||
-rw-r--r-- | test/py/tests/test_gpio.py | 16 |
2 files changed, 35 insertions, 5 deletions
@@ -12,6 +12,7 @@ #include <dm.h> #include <log.h> #include <malloc.h> +#include <env.h> #include <asm/gpio.h> #include <linux/err.h> @@ -25,6 +26,7 @@ enum gpio_cmd { GPIOC_SET, GPIOC_CLEAR, GPIOC_TOGGLE, + GPIOC_READ, }; #if defined(CONFIG_DM_GPIO) && !defined(gpio_status) @@ -124,7 +126,7 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc, unsigned int gpio; enum gpio_cmd sub_cmd; int value; - const char *str_cmd, *str_gpio = NULL; + const char *str_cmd, *str_gpio, *str_var = NULL; int ret; #ifdef CONFIG_DM_GPIO bool all = false; @@ -137,12 +139,19 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc, argc -= 2; argv += 2; #ifdef CONFIG_DM_GPIO - if (argc > 0 && !strcmp(*argv, "-a")) { + if (argc > 0 && !strncmp(str_cmd, "status", 2) && !strcmp(*argv, "-a")) { all = true; argc--; argv++; } #endif + if (argc > 0 && !strncmp(str_cmd, "read", 2)) { + if (argc < 2) + goto show_usage; + str_var = *argv; + argc--; + argv++; + } if (argc > 0) str_gpio = *argv; if (!strncmp(str_cmd, "status", 2)) { @@ -174,6 +183,9 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc, case 't': sub_cmd = GPIOC_TOGGLE; break; + case 'r': + sub_cmd = GPIOC_READ; + break; default: goto show_usage; } @@ -205,7 +217,7 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc, } /* finally, let's do it: set direction and exec command */ - if (sub_cmd == GPIOC_INPUT) { + if (sub_cmd == GPIOC_INPUT || sub_cmd == GPIOC_READ) { gpio_direction_input(gpio); value = gpio_get_value(gpio); } else { @@ -233,9 +245,11 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc, goto err; } else { printf("%d\n", value); + if (sub_cmd == GPIOC_READ) + env_set_ulong(str_var, (ulong)value); } - if (sub_cmd != GPIOC_INPUT && !IS_ERR_VALUE(value)) { + if (sub_cmd != GPIOC_INPUT && sub_cmd != GPIOC_READ && !IS_ERR_VALUE(value)) { int nval = gpio_get_value(gpio); if (IS_ERR_VALUE(nval)) { @@ -267,4 +281,6 @@ U_BOOT_CMD(gpio, 4, 0, do_gpio, "query and control gpio pins", "<input|set|clear|toggle> <pin>\n" " - input/set/clear/toggle the specified pin\n" + "gpio read <name> <pin>\n" + " - set environment variable 'name' to the specified pin\n" "gpio status [-a] [<bank> | <pin>] - show [all/claimed] GPIOs"); diff --git a/test/py/tests/test_gpio.py b/test/py/tests/test_gpio.py index 109649e..2def364 100644 --- a/test/py/tests/test_gpio.py +++ b/test/py/tests/test_gpio.py @@ -46,7 +46,6 @@ def test_gpio_exit_statuses(u_boot_console): response = u_boot_console.run_command('gpio input 200; echo rc:$?') assert(expected_response in response) - """ Generic Tests for 'gpio' command on sandbox and real hardware. The below sequence of tests rely on env__gpio_dev_config for configuration values of gpio pins. @@ -208,3 +207,18 @@ def test_gpio_input_generic(u_boot_console): response = u_boot_console.run_command(cmd) good_response = gpio_set_value assert good_response in response + +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('cmd_gpio') +def test_gpio_read(u_boot_console): + """Test that gpio read correctly sets the variable to the value of a gpio pin.""" + + response = u_boot_console.run_command('gpio read var 0; echo val:$var') + expected_response = 'val:0' + assert(expected_response in response) + response = u_boot_console.run_command('gpio toggle 0; gpio read var 0; echo val:$var') + expected_response = 'val:1' + assert(expected_response in response) + response = u_boot_console.run_command('setenv var; gpio read var nonexistent-gpio; echo val:$var') + expected_response = 'val:' + assert(expected_response in response) |