Skip to content

Commit dd2b8c1

Browse files
diegorondinitrini
authored andcommitted
cmd: gpio: Add gpio read subcommand
As explained in commit 4af2a33 ("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>
1 parent 270f7fd commit dd2b8c1

File tree

4 files changed

+64
-3
lines changed

4 files changed

+64
-3
lines changed

cmd/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,13 @@ config CMD_GPIO
996996
help
997997
GPIO support.
998998

999+
config CMD_GPIO_READ
1000+
bool "gpio read - save GPIO value to variable"
1001+
depends on CMD_GPIO
1002+
help
1003+
Enables the 'gpio read' command that saves the value
1004+
of a GPIO pin to a variable.
1005+
9991006
config CMD_PWM
10001007
bool "pwm"
10011008
depends on DM_PWM

cmd/gpio.c

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#include <dm.h>
1313
#include <log.h>
1414
#include <malloc.h>
15+
#ifdef CONFIG_CMD_GPIO_READ
16+
#include <env.h>
17+
#endif
1518
#include <asm/gpio.h>
1619
#include <linux/err.h>
1720

@@ -25,6 +28,9 @@ enum gpio_cmd {
2528
GPIOC_SET,
2629
GPIOC_CLEAR,
2730
GPIOC_TOGGLE,
31+
#ifdef CONFIG_CMD_GPIO_READ
32+
GPIOC_READ,
33+
#endif
2834
};
2935

3036
#if defined(CONFIG_DM_GPIO) && !defined(gpio_status)
@@ -125,6 +131,9 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc,
125131
enum gpio_cmd sub_cmd;
126132
int value;
127133
const char *str_cmd, *str_gpio = NULL;
134+
#ifdef CONFIG_CMD_GPIO_READ
135+
const char *str_var = NULL;
136+
#endif
128137
int ret;
129138
#ifdef CONFIG_DM_GPIO
130139
bool all = false;
@@ -137,11 +146,20 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc,
137146
argc -= 2;
138147
argv += 2;
139148
#ifdef CONFIG_DM_GPIO
140-
if (argc > 0 && !strcmp(*argv, "-a")) {
149+
if (argc > 0 && !strncmp(str_cmd, "status", 2) && !strcmp(*argv, "-a")) {
141150
all = true;
142151
argc--;
143152
argv++;
144153
}
154+
#endif
155+
#ifdef CONFIG_CMD_GPIO_READ
156+
if (argc > 0 && !strncmp(str_cmd, "read", 2)) {
157+
if (argc < 2)
158+
goto show_usage;
159+
str_var = *argv;
160+
argc--;
161+
argv++;
162+
}
145163
#endif
146164
if (argc > 0)
147165
str_gpio = *argv;
@@ -174,6 +192,11 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc,
174192
case 't':
175193
sub_cmd = GPIOC_TOGGLE;
176194
break;
195+
#ifdef CONFIG_CMD_GPIO_READ
196+
case 'r':
197+
sub_cmd = GPIOC_READ;
198+
break;
199+
#endif
177200
default:
178201
goto show_usage;
179202
}
@@ -205,7 +228,11 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc,
205228
}
206229

207230
/* finally, let's do it: set direction and exec command */
208-
if (sub_cmd == GPIOC_INPUT) {
231+
if (sub_cmd == GPIOC_INPUT
232+
#ifdef CONFIG_CMD_GPIO_READ
233+
|| sub_cmd == GPIOC_READ
234+
#endif
235+
) {
209236
gpio_direction_input(gpio);
210237
value = gpio_get_value(gpio);
211238
} else {
@@ -233,9 +260,17 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc,
233260
goto err;
234261
} else {
235262
printf("%d\n", value);
263+
#ifdef CONFIG_CMD_GPIO_READ
264+
if (sub_cmd == GPIOC_READ)
265+
env_set_ulong(str_var, (ulong)value);
266+
#endif
236267
}
237268

238-
if (sub_cmd != GPIOC_INPUT && !IS_ERR_VALUE(value)) {
269+
if (sub_cmd != GPIOC_INPUT && !IS_ERR_VALUE(value)
270+
#ifdef CONFIG_CMD_GPIO_READ
271+
&& sub_cmd != GPIOC_READ
272+
#endif
273+
) {
239274
int nval = gpio_get_value(gpio);
240275

241276
if (IS_ERR_VALUE(nval)) {
@@ -267,4 +302,8 @@ U_BOOT_CMD(gpio, 4, 0, do_gpio,
267302
"query and control gpio pins",
268303
"<input|set|clear|toggle> <pin>\n"
269304
" - input/set/clear/toggle the specified pin\n"
305+
#ifdef CONFIG_CMD_GPIO_READ
306+
"gpio read <name> <pin>\n"
307+
" - set environment variable 'name' to the specified pin\n"
308+
#endif
270309
"gpio status [-a] [<bank> | <pin>] - show [all/claimed] GPIOs");

configs/sandbox_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ CONFIG_CMD_UNZIP=y
6060
CONFIG_CMD_BIND=y
6161
CONFIG_CMD_DEMO=y
6262
CONFIG_CMD_GPIO=y
63+
CONFIG_CMD_GPIO_READ=y
6364
CONFIG_CMD_PWM=y
6465
CONFIG_CMD_GPT=y
6566
CONFIG_CMD_GPT_RENAME=y

test/py/tests/test_gpio.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,20 @@ def test_gpio_exit_statuses(u_boot_console):
4646
response = u_boot_console.run_command('gpio input 200; echo rc:$?')
4747
assert(expected_response in response)
4848

49+
@pytest.mark.boardspec('sandbox')
50+
@pytest.mark.buildconfigspec('cmd_gpio')
51+
def test_gpio_read(u_boot_console):
52+
"""Test that gpio read correctly sets the variable to the value of a gpio pin."""
53+
54+
response = u_boot_console.run_command('gpio read var 0; echo val:$var,rc:$?')
55+
expected_response = 'val:0,rc:0'
56+
assert(expected_response in response)
57+
response = u_boot_console.run_command('gpio toggle 0; gpio read var 0; echo val:$var,rc:$?')
58+
expected_response = 'val:1,rc:0'
59+
assert(expected_response in response)
60+
response = u_boot_console.run_command('setenv var; gpio read var nonexistent-gpio; echo val:$var,rc:$?')
61+
expected_response = 'val:,rc:1'
62+
assert(expected_response in response)
4963

5064
"""
5165
Generic Tests for 'gpio' command on sandbox and real hardware.

0 commit comments

Comments
 (0)