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 */
20 const char *label
; /* label given by requester */
21 u8 flags
; /* flags (GPIOF_...) */
24 /* Access routines for GPIO state */
25 static u8
*get_gpio_flags(struct udevice
*dev
, unsigned offset
)
27 struct gpio_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
28 struct gpio_state
*state
= dev_get_priv(dev
);
30 if (offset
>= uc_priv
->gpio_count
) {
31 static u8 invalid_flags
;
32 printf("sandbox_gpio: error: invalid gpio %u\n", offset
);
33 return &invalid_flags
;
36 return &state
[offset
].flags
;
39 static int get_gpio_flag(struct udevice
*dev
, unsigned offset
, int flag
)
41 return (*get_gpio_flags(dev
, offset
) & flag
) != 0;
44 static int set_gpio_flag(struct udevice
*dev
, unsigned offset
, int flag
,
47 u8
*gpio
= get_gpio_flags(dev
, offset
);
58 * Back-channel sandbox-internal-only access to GPIO state
61 int sandbox_gpio_get_value(struct udevice
*dev
, unsigned offset
)
63 if (get_gpio_flag(dev
, offset
, GPIOF_OUTPUT
))
64 debug("sandbox_gpio: get_value on output gpio %u\n", offset
);
65 return get_gpio_flag(dev
, offset
, GPIOF_HIGH
);
68 int sandbox_gpio_set_value(struct udevice
*dev
, unsigned offset
, int value
)
70 return set_gpio_flag(dev
, offset
, GPIOF_HIGH
, value
);
73 int sandbox_gpio_get_direction(struct udevice
*dev
, unsigned offset
)
75 return get_gpio_flag(dev
, offset
, GPIOF_OUTPUT
);
78 int sandbox_gpio_set_direction(struct udevice
*dev
, unsigned offset
, int output
)
80 return set_gpio_flag(dev
, offset
, GPIOF_OUTPUT
, output
);
84 * These functions implement the public interface within U-Boot
87 /* set GPIO port 'offset' as an input */
88 static int sb_gpio_direction_input(struct udevice
*dev
, unsigned offset
)
90 debug("%s: offset:%u\n", __func__
, offset
);
92 return sandbox_gpio_set_direction(dev
, offset
, 0);
95 /* set GPIO port 'offset' as an output, with polarity 'value' */
96 static int sb_gpio_direction_output(struct udevice
*dev
, unsigned offset
,
99 debug("%s: offset:%u, value = %d\n", __func__
, offset
, value
);
101 return sandbox_gpio_set_direction(dev
, offset
, 1) |
102 sandbox_gpio_set_value(dev
, offset
, value
);
105 /* read GPIO IN value of port 'offset' */
106 static int sb_gpio_get_value(struct udevice
*dev
, unsigned offset
)
108 debug("%s: offset:%u\n", __func__
, offset
);
110 return sandbox_gpio_get_value(dev
, offset
);
113 /* write GPIO OUT value to port 'offset' */
114 static int sb_gpio_set_value(struct udevice
*dev
, unsigned offset
, int value
)
116 debug("%s: offset:%u, value = %d\n", __func__
, offset
, value
);
118 if (!sandbox_gpio_get_direction(dev
, offset
)) {
119 printf("sandbox_gpio: error: set_value on input gpio %u\n",
124 return sandbox_gpio_set_value(dev
, offset
, value
);
127 static int sb_gpio_get_function(struct udevice
*dev
, unsigned offset
)
129 if (get_gpio_flag(dev
, offset
, GPIOF_OUTPUT
))
134 static int sb_gpio_xlate(struct udevice
*dev
, struct gpio_desc
*desc
,
135 struct fdtdec_phandle_args
*args
)
137 desc
->offset
= args
->args
[0];
138 if (args
->args_count
< 2)
140 if (args
->args
[1] & GPIO_ACTIVE_LOW
)
141 desc
->flags
|= GPIOD_ACTIVE_LOW
;
142 if (args
->args
[1] & 2)
143 desc
->flags
|= GPIOD_IS_IN
;
144 if (args
->args
[1] & 4)
145 desc
->flags
|= GPIOD_IS_OUT
;
146 if (args
->args
[1] & 8)
147 desc
->flags
|= GPIOD_IS_OUT_ACTIVE
;
152 static const struct dm_gpio_ops gpio_sandbox_ops
= {
153 .direction_input
= sb_gpio_direction_input
,
154 .direction_output
= sb_gpio_direction_output
,
155 .get_value
= sb_gpio_get_value
,
156 .set_value
= sb_gpio_set_value
,
157 .get_function
= sb_gpio_get_function
,
158 .xlate
= sb_gpio_xlate
,
161 static int sandbox_gpio_ofdata_to_platdata(struct udevice
*dev
)
163 struct gpio_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
165 uc_priv
->gpio_count
= fdtdec_get_int(gd
->fdt_blob
, dev
->of_offset
,
167 uc_priv
->bank_name
= fdt_getprop(gd
->fdt_blob
, dev
->of_offset
,
168 "gpio-bank-name", NULL
);
173 static int gpio_sandbox_probe(struct udevice
*dev
)
175 struct gpio_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
177 if (dev
->of_offset
== -1) {
178 /* Tell the uclass how many GPIOs we have */
179 uc_priv
->gpio_count
= CONFIG_SANDBOX_GPIO_COUNT
;
182 dev
->priv
= calloc(sizeof(struct gpio_state
), uc_priv
->gpio_count
);
187 static int gpio_sandbox_remove(struct udevice
*dev
)
194 static const struct udevice_id sandbox_gpio_ids
[] = {
195 { .compatible
= "sandbox,gpio" },
199 U_BOOT_DRIVER(gpio_sandbox
) = {
200 .name
= "gpio_sandbox",
202 .of_match
= sandbox_gpio_ids
,
203 .ofdata_to_platdata
= sandbox_gpio_ofdata_to_platdata
,
204 .probe
= gpio_sandbox_probe
,
205 .remove
= gpio_sandbox_remove
,
206 .ops
= &gpio_sandbox_ops
,