1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include <common.h>
23#include <asm/gpio.h>
24
25
26#define GPIOF_OUTPUT (1 << 0)
27#define GPIOF_HIGH (1 << 1)
28#define GPIOF_RESERVED (1 << 2)
29
30struct gpio_state {
31 const char *label;
32 u8 flags;
33};
34
35
36
37
38
39static struct gpio_state state[CONFIG_SANDBOX_GPIO_COUNT];
40
41
42static u8 *get_gpio_flags(unsigned gp)
43{
44
45 assert(gp < ARRAY_SIZE(state));
46 if (gp >= ARRAY_SIZE(state)) {
47 static u8 invalid_flags;
48 printf("sandbox_gpio: error: invalid gpio %u\n", gp);
49 return &invalid_flags;
50 }
51
52 return &state[gp].flags;
53}
54
55static int get_gpio_flag(unsigned gp, int flag)
56{
57 return (*get_gpio_flags(gp) & flag) != 0;
58}
59
60static int set_gpio_flag(unsigned gp, int flag, int value)
61{
62 u8 *gpio = get_gpio_flags(gp);
63
64 if (value)
65 *gpio |= flag;
66 else
67 *gpio &= ~flag;
68
69 return 0;
70}
71
72static int check_reserved(unsigned gpio, const char *func)
73{
74 if (!get_gpio_flag(gpio, GPIOF_RESERVED)) {
75 printf("sandbox_gpio: %s: error: gpio %u not reserved\n",
76 func, gpio);
77 return -1;
78 }
79
80 return 0;
81}
82
83
84
85
86
87int sandbox_gpio_get_value(unsigned gp)
88{
89 if (get_gpio_flag(gp, GPIOF_OUTPUT))
90 debug("sandbox_gpio: get_value on output gpio %u\n", gp);
91 return get_gpio_flag(gp, GPIOF_HIGH);
92}
93
94int sandbox_gpio_set_value(unsigned gp, int value)
95{
96 return set_gpio_flag(gp, GPIOF_HIGH, value);
97}
98
99int sandbox_gpio_get_direction(unsigned gp)
100{
101 return get_gpio_flag(gp, GPIOF_OUTPUT);
102}
103
104int sandbox_gpio_set_direction(unsigned gp, int output)
105{
106 return set_gpio_flag(gp, GPIOF_OUTPUT, output);
107}
108
109
110
111
112
113
114int gpio_direction_input(unsigned gp)
115{
116 debug("%s: gp:%u\n", __func__, gp);
117
118 if (check_reserved(gp, __func__))
119 return -1;
120
121 return sandbox_gpio_set_direction(gp, 0);
122}
123
124
125int gpio_direction_output(unsigned gp, int value)
126{
127 debug("%s: gp:%u, value = %d\n", __func__, gp, value);
128
129 if (check_reserved(gp, __func__))
130 return -1;
131
132 return sandbox_gpio_set_direction(gp, 1) |
133 sandbox_gpio_set_value(gp, value);
134}
135
136
137int gpio_get_value(unsigned gp)
138{
139 debug("%s: gp:%u\n", __func__, gp);
140
141 if (check_reserved(gp, __func__))
142 return -1;
143
144 return sandbox_gpio_get_value(gp);
145}
146
147
148int gpio_set_value(unsigned gp, int value)
149{
150 debug("%s: gp:%u, value = %d\n", __func__, gp, value);
151
152 if (check_reserved(gp, __func__))
153 return -1;
154
155 if (!sandbox_gpio_get_direction(gp)) {
156 printf("sandbox_gpio: error: set_value on input gpio %u\n", gp);
157 return -1;
158 }
159
160 return sandbox_gpio_set_value(gp, value);
161}
162
163int gpio_request(unsigned gp, const char *label)
164{
165 debug("%s: gp:%u, label:%s\n", __func__, gp, label);
166
167 if (gp >= ARRAY_SIZE(state)) {
168 printf("sandbox_gpio: error: invalid gpio %u\n", gp);
169 return -1;
170 }
171
172 if (get_gpio_flag(gp, GPIOF_RESERVED)) {
173 printf("sandbox_gpio: error: gpio %u already reserved\n", gp);
174 return -1;
175 }
176
177 state[gp].label = label;
178 return set_gpio_flag(gp, GPIOF_RESERVED, 1);
179}
180
181int gpio_free(unsigned gp)
182{
183 debug("%s: gp:%u\n", __func__, gp);
184
185 if (check_reserved(gp, __func__))
186 return -1;
187
188 state[gp].label = NULL;
189 return set_gpio_flag(gp, GPIOF_RESERVED, 0);
190}
191
192
193void gpio_info(void)
194{
195 unsigned gpio;
196
197 puts("Sandbox GPIOs\n");
198
199 for (gpio = 0; gpio < ARRAY_SIZE(state); ++gpio) {
200 const char *label = state[gpio].label;
201
202 printf("%4d: %s: %d [%c] %s\n",
203 gpio,
204 sandbox_gpio_get_direction(gpio) ? "out" : " in",
205 sandbox_gpio_get_value(gpio),
206 get_gpio_flag(gpio, GPIOF_RESERVED) ? 'x' : ' ',
207 label ? label : "");
208 }
209}
210