2 * Copyright (c) 2011 The Chromium OS Authors.
3 * SPDX-License-Identifier: GPL-2.0+
11 #include <dt-bindings/gpio/gpio.h>
13 DECLARE_GLOBAL_DATA_PTR
;
15 /* Flags for each GPIO */
16 #define GPIOF_OUTPUT (1 << 0) /* Currently set as an output */
17 #define GPIOF_HIGH (1 << 1) /* Currently set high */
18 #define GPIOF_ODR (1 << 2) /* Currently set to open drain mode */
21 const char *label
; /* label given by requester */
22 u8 flags
; /* flags (GPIOF_...) */
25 /* Access routines for GPIO state */
26 static u8
*get_gpio_flags(struct udevice
*dev
, unsigned offset
)
28 struct gpio_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
29 struct gpio_state
*state
= dev_get_priv(dev
);
31 if (offset
>= uc_priv
->gpio_count
) {
32 static u8 invalid_flags
;
33 printf("sandbox_gpio: error: invalid gpio %u\n", offset
);
34 return &invalid_flags
;
37 return &state
[offset
].flags
;
40 static int get_gpio_flag(struct udevice
*dev
, unsigned offset
, int flag
)
42 return (*get_gpio_flags(dev
, offset
) & flag
) != 0;
45 static int set_gpio_flag(struct udevice
*dev
, unsigned offset
, int flag
,
48 u8
*gpio
= get_gpio_flags(dev
, offset
);
59 * Back-channel sandbox-internal-only access to GPIO state
62 int sandbox_gpio_get_value(struct udevice
*dev
, unsigned offset
)
64 if (get_gpio_flag(dev
, offset
, GPIOF_OUTPUT
))
65 debug("sandbox_gpio: get_value on output gpio %u\n", offset
);
66 return get_gpio_flag(dev
, offset
, GPIOF_HIGH
);
69 int sandbox_gpio_set_value(struct udevice
*dev
, unsigned offset
, int value
)
71 return set_gpio_flag(dev
, offset
, GPIOF_HIGH
, value
);
74 int sandbox_gpio_get_open_drain(struct udevice
*dev
, unsigned offset
)
76 return get_gpio_flag(dev
, offset
, GPIOF_ODR
);
79 int sandbox_gpio_set_open_drain(struct udevice
*dev
, unsigned offset
, int value
)
81 return set_gpio_flag(dev
, offset
, GPIOF_ODR
, value
);
84 int sandbox_gpio_get_direction(struct udevice
*dev
, unsigned offset
)
86 return get_gpio_flag(dev
, offset
, GPIOF_OUTPUT
);
89 int sandbox_gpio_set_direction(struct udevice
*dev
, unsigned offset
, int output
)
91 return set_gpio_flag(dev
, offset
, GPIOF_OUTPUT
, output
);
95 * These functions implement the public interface within U-Boot
98 /* set GPIO port 'offset' as an input */
99 static int sb_gpio_direction_input(struct udevice
*dev
, unsigned offset
)
101 debug("%s: offset:%u\n", __func__
, offset
);
103 return sandbox_gpio_set_direction(dev
, offset
, 0);
106 /* set GPIO port 'offset' as an output, with polarity 'value' */
107 static int sb_gpio_direction_output(struct udevice
*dev
, unsigned offset
,
110 debug("%s: offset:%u, value = %d\n", __func__
, offset
, value
);
112 return sandbox_gpio_set_direction(dev
, offset
, 1) |
113 sandbox_gpio_set_value(dev
, offset
, value
);
116 /* read GPIO IN value of port 'offset' */
117 static int sb_gpio_get_value(struct udevice
*dev
, unsigned offset
)
119 debug("%s: offset:%u\n", __func__
, offset
);
121 return sandbox_gpio_get_value(dev
, offset
);
124 /* write GPIO OUT value to port 'offset' */
125 static int sb_gpio_set_value(struct udevice
*dev
, unsigned offset
, int value
)
127 debug("%s: offset:%u, value = %d\n", __func__
, offset
, value
);
129 if (!sandbox_gpio_get_direction(dev
, offset
)) {
130 printf("sandbox_gpio: error: set_value on input gpio %u\n",
135 return sandbox_gpio_set_value(dev
, offset
, value
);
138 /* read GPIO ODR value of port 'offset' */
139 static int sb_gpio_get_open_drain(struct udevice
*dev
, unsigned offset
)
141 debug("%s: offset:%u\n", __func__
, offset
);
143 return sandbox_gpio_get_open_drain(dev
, offset
);
146 /* write GPIO ODR value to port 'offset' */
147 static int sb_gpio_set_open_drain(struct udevice
*dev
, unsigned offset
, int value
)
149 debug("%s: offset:%u, value = %d\n", __func__
, offset
, value
);
151 if (!sandbox_gpio_get_direction(dev
, offset
)) {
152 printf("sandbox_gpio: error: set_open_drain on input gpio %u\n",
157 return sandbox_gpio_set_open_drain(dev
, offset
, value
);
160 static int sb_gpio_get_function(struct udevice
*dev
, unsigned offset
)
162 if (get_gpio_flag(dev
, offset
, GPIOF_OUTPUT
))
167 static int sb_gpio_xlate(struct udevice
*dev
, struct gpio_desc
*desc
,
168 struct fdtdec_phandle_args
*args
)
170 desc
->offset
= args
->args
[0];
171 if (args
->args_count
< 2)
173 if (args
->args
[1] & GPIO_ACTIVE_LOW
)
174 desc
->flags
|= GPIOD_ACTIVE_LOW
;
175 if (args
->args
[1] & 2)
176 desc
->flags
|= GPIOD_IS_IN
;
177 if (args
->args
[1] & 4)
178 desc
->flags
|= GPIOD_IS_OUT
;
179 if (args
->args
[1] & 8)
180 desc
->flags
|= GPIOD_IS_OUT_ACTIVE
;
185 static const struct dm_gpio_ops gpio_sandbox_ops
= {
186 .direction_input
= sb_gpio_direction_input
,
187 .direction_output
= sb_gpio_direction_output
,
188 .get_value
= sb_gpio_get_value
,
189 .set_value
= sb_gpio_set_value
,
190 .get_open_drain
= sb_gpio_get_open_drain
,
191 .set_open_drain
= sb_gpio_set_open_drain
,
192 .get_function
= sb_gpio_get_function
,
193 .xlate
= sb_gpio_xlate
,
196 static int sandbox_gpio_ofdata_to_platdata(struct udevice
*dev
)
198 struct gpio_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
200 uc_priv
->gpio_count
= fdtdec_get_int(gd
->fdt_blob
, dev
->of_offset
,
202 uc_priv
->bank_name
= fdt_getprop(gd
->fdt_blob
, dev
->of_offset
,
203 "gpio-bank-name", NULL
);
208 static int gpio_sandbox_probe(struct udevice
*dev
)
210 struct gpio_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
212 if (dev
->of_offset
== -1) {
213 /* Tell the uclass how many GPIOs we have */
214 uc_priv
->gpio_count
= CONFIG_SANDBOX_GPIO_COUNT
;
217 dev
->priv
= calloc(sizeof(struct gpio_state
), uc_priv
->gpio_count
);
222 static int gpio_sandbox_remove(struct udevice
*dev
)
229 static const struct udevice_id sandbox_gpio_ids
[] = {
230 { .compatible
= "sandbox,gpio" },
234 U_BOOT_DRIVER(gpio_sandbox
) = {
235 .name
= "gpio_sandbox",
237 .of_match
= sandbox_gpio_ids
,
238 .ofdata_to_platdata
= sandbox_gpio_ofdata_to_platdata
,
239 .probe
= gpio_sandbox_probe
,
240 .remove
= gpio_sandbox_remove
,
241 .ops
= &gpio_sandbox_ops
,