1 /*
2 * Copyright (c) 2022 Meta
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/drivers/gpio.h>
9 #include <zephyr/ztest.h>
10
11 #define TEST_NODE DT_GPIO_CTLR(DT_ALIAS(led0), gpios)
12 #define TEST_PIN DT_GPIO_PIN(DT_ALIAS(led0), gpios)
13 #define TEST_PIN_DTS_FLAGS DT_GPIO_FLAGS(DT_ALIAS(led0), gpios)
14
15 struct gpio_get_direction_fixture {
16 const struct device *port;
17 gpio_pin_t pin;
18 gpio_flags_t flags;
19 };
20
gpio_get_direction_setup(void)21 static void *gpio_get_direction_setup(void)
22 {
23 static struct gpio_get_direction_fixture fixture;
24
25 fixture.pin = TEST_PIN;
26 fixture.port = DEVICE_DT_GET(TEST_NODE);
27
28 return &fixture;
29 }
30
gpio_get_direction_before(void * arg)31 static void gpio_get_direction_before(void *arg)
32 {
33 struct gpio_get_direction_fixture *fixture = (struct gpio_get_direction_fixture *)arg;
34
35 zassert_true(device_is_ready(fixture->port), "GPIO device is not ready");
36 }
37
common(struct gpio_get_direction_fixture * fixture)38 static void common(struct gpio_get_direction_fixture *fixture)
39 {
40 int rv;
41
42 rv = gpio_pin_configure(fixture->port, fixture->pin, fixture->flags);
43 if (rv == -ENOTSUP) {
44 /* some drivers / hw might not support e.g. input-output or disconnect */
45 ztest_test_skip();
46 }
47
48 zassert_ok(rv, "gpio_pin_configure() failed: %d", rv);
49 }
50
ZTEST_F(gpio_get_direction,test_disconnect)51 ZTEST_F(gpio_get_direction, test_disconnect)
52 {
53 int rv;
54
55 fixture->flags = GPIO_DISCONNECTED;
56 common(fixture);
57
58 rv = gpio_pin_is_input(fixture->port, fixture->pin);
59 if (rv == -ENOSYS) {
60 /* gpio_pin_direction() is not supported in the driver */
61 ztest_test_skip();
62 }
63
64 zassert_equal(false, rv, "gpio_pin_is_input() failed: %d", rv);
65
66 rv = gpio_pin_is_output(fixture->port, fixture->pin);
67 zassert_equal(false, rv, "gpio_pin_is_output() failed: %d", rv);
68 }
69
ZTEST_F(gpio_get_direction,test_input)70 ZTEST_F(gpio_get_direction, test_input)
71 {
72 int rv;
73 fixture->flags = GPIO_INPUT;
74
75 common(fixture);
76
77 rv = gpio_pin_is_input(fixture->port, fixture->pin);
78 if (rv == -ENOSYS) {
79 /* gpio_pin_direction() is not supported in the driver */
80 ztest_test_skip();
81 }
82
83 zassert_equal(true, rv, "gpio_pin_is_input() failed: %d", rv);
84
85 rv = gpio_pin_is_output(fixture->port, fixture->pin);
86 zassert_equal(false, rv, "gpio_pin_is_output() failed: %d", rv);
87 }
88
ZTEST_F(gpio_get_direction,test_output)89 ZTEST_F(gpio_get_direction, test_output)
90 {
91 int rv;
92 fixture->flags = GPIO_OUTPUT | GPIO_OUTPUT_INIT_LOW;
93
94 common(fixture);
95
96 rv = gpio_pin_is_input(fixture->port, fixture->pin);
97 if (rv == -ENOSYS) {
98 /* gpio_pin_direction() is not supported in the driver */
99 ztest_test_skip();
100 }
101
102 zassert_equal(false, rv, "gpio_pin_is_input() failed: %d", rv);
103
104 rv = gpio_pin_is_output(fixture->port, fixture->pin);
105 zassert_equal(true, rv, "gpio_pin_is_output() failed: %d", rv);
106 }
107
ZTEST_F(gpio_get_direction,test_input_output)108 ZTEST_F(gpio_get_direction, test_input_output)
109 {
110 int rv;
111 fixture->flags = GPIO_INPUT | GPIO_OUTPUT | GPIO_OUTPUT_INIT_LOW;
112
113 common(fixture);
114
115 rv = gpio_pin_is_input(fixture->port, fixture->pin);
116 if (rv == -ENOSYS) {
117 /* some drivers / gpio hw do not support input-output mode */
118 ztest_test_skip();
119 }
120
121 zassert_equal(true, rv, "gpio_pin_is_input() failed: %d", rv);
122
123 rv = gpio_pin_is_output(fixture->port, fixture->pin);
124 zassert_equal(true, rv, "gpio_pin_is_output() failed: %d", rv);
125 }
126
127 ZTEST_SUITE(gpio_get_direction, NULL, gpio_get_direction_setup, gpio_get_direction_before, NULL,
128 NULL);
129