mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 15:41:40 +00:00
cmd: gpio: Add gpio read
subcommand
As explained in commit 4af2a33ee5
("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.
CONFIG_CMD_GPIO_READ is used to enable the `gpio read` command.
Signed-off-by: Diego Rondini <diego.rondini@kynetics.com>
This commit is contained in:
parent
270f7fd25b
commit
dd2b8c1155
4 changed files with 64 additions and 3 deletions
|
@ -996,6 +996,13 @@ config CMD_GPIO
|
|||
help
|
||||
GPIO support.
|
||||
|
||||
config CMD_GPIO_READ
|
||||
bool "gpio read - save GPIO value to variable"
|
||||
depends on CMD_GPIO
|
||||
help
|
||||
Enables the 'gpio read' command that saves the value
|
||||
of a GPIO pin to a variable.
|
||||
|
||||
config CMD_PWM
|
||||
bool "pwm"
|
||||
depends on DM_PWM
|
||||
|
|
45
cmd/gpio.c
45
cmd/gpio.c
|
@ -12,6 +12,9 @@
|
|||
#include <dm.h>
|
||||
#include <log.h>
|
||||
#include <malloc.h>
|
||||
#ifdef CONFIG_CMD_GPIO_READ
|
||||
#include <env.h>
|
||||
#endif
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
|
@ -25,6 +28,9 @@ enum gpio_cmd {
|
|||
GPIOC_SET,
|
||||
GPIOC_CLEAR,
|
||||
GPIOC_TOGGLE,
|
||||
#ifdef CONFIG_CMD_GPIO_READ
|
||||
GPIOC_READ,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DM_GPIO) && !defined(gpio_status)
|
||||
|
@ -125,6 +131,9 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc,
|
|||
enum gpio_cmd sub_cmd;
|
||||
int value;
|
||||
const char *str_cmd, *str_gpio = NULL;
|
||||
#ifdef CONFIG_CMD_GPIO_READ
|
||||
const char *str_var = NULL;
|
||||
#endif
|
||||
int ret;
|
||||
#ifdef CONFIG_DM_GPIO
|
||||
bool all = false;
|
||||
|
@ -137,11 +146,20 @@ 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
|
||||
#ifdef CONFIG_CMD_GPIO_READ
|
||||
if (argc > 0 && !strncmp(str_cmd, "read", 2)) {
|
||||
if (argc < 2)
|
||||
goto show_usage;
|
||||
str_var = *argv;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
#endif
|
||||
if (argc > 0)
|
||||
str_gpio = *argv;
|
||||
|
@ -174,6 +192,11 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc,
|
|||
case 't':
|
||||
sub_cmd = GPIOC_TOGGLE;
|
||||
break;
|
||||
#ifdef CONFIG_CMD_GPIO_READ
|
||||
case 'r':
|
||||
sub_cmd = GPIOC_READ;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
goto show_usage;
|
||||
}
|
||||
|
@ -205,7 +228,11 @@ 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
|
||||
#ifdef CONFIG_CMD_GPIO_READ
|
||||
|| sub_cmd == GPIOC_READ
|
||||
#endif
|
||||
) {
|
||||
gpio_direction_input(gpio);
|
||||
value = gpio_get_value(gpio);
|
||||
} else {
|
||||
|
@ -233,9 +260,17 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc,
|
|||
goto err;
|
||||
} else {
|
||||
printf("%d\n", value);
|
||||
#ifdef CONFIG_CMD_GPIO_READ
|
||||
if (sub_cmd == GPIOC_READ)
|
||||
env_set_ulong(str_var, (ulong)value);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (sub_cmd != GPIOC_INPUT && !IS_ERR_VALUE(value)) {
|
||||
if (sub_cmd != GPIOC_INPUT && !IS_ERR_VALUE(value)
|
||||
#ifdef CONFIG_CMD_GPIO_READ
|
||||
&& sub_cmd != GPIOC_READ
|
||||
#endif
|
||||
) {
|
||||
int nval = gpio_get_value(gpio);
|
||||
|
||||
if (IS_ERR_VALUE(nval)) {
|
||||
|
@ -267,4 +302,8 @@ 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"
|
||||
#ifdef CONFIG_CMD_GPIO_READ
|
||||
"gpio read <name> <pin>\n"
|
||||
" - set environment variable 'name' to the specified pin\n"
|
||||
#endif
|
||||
"gpio status [-a] [<bank> | <pin>] - show [all/claimed] GPIOs");
|
||||
|
|
|
@ -60,6 +60,7 @@ CONFIG_CMD_UNZIP=y
|
|||
CONFIG_CMD_BIND=y
|
||||
CONFIG_CMD_DEMO=y
|
||||
CONFIG_CMD_GPIO=y
|
||||
CONFIG_CMD_GPIO_READ=y
|
||||
CONFIG_CMD_PWM=y
|
||||
CONFIG_CMD_GPT=y
|
||||
CONFIG_CMD_GPT_RENAME=y
|
||||
|
|
|
@ -46,6 +46,20 @@ def test_gpio_exit_statuses(u_boot_console):
|
|||
response = u_boot_console.run_command('gpio input 200; echo rc:$?')
|
||||
assert(expected_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,rc:$?')
|
||||
expected_response = 'val:0,rc:0'
|
||||
assert(expected_response in response)
|
||||
response = u_boot_console.run_command('gpio toggle 0; gpio read var 0; echo val:$var,rc:$?')
|
||||
expected_response = 'val:1,rc:0'
|
||||
assert(expected_response in response)
|
||||
response = u_boot_console.run_command('setenv var; gpio read var nonexistent-gpio; echo val:$var,rc:$?')
|
||||
expected_response = 'val:,rc:1'
|
||||
assert(expected_response in response)
|
||||
|
||||
"""
|
||||
Generic Tests for 'gpio' command on sandbox and real hardware.
|
||||
|
|
Loading…
Reference in a new issue