1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3 * Copyright (c) 2016, Linaro Limited
4 */
5
6 #ifndef __DRIVERS_GPIO_H
7 #define __DRIVERS_GPIO_H
8
9 #include <assert.h>
10 #include <dt-bindings/gpio/gpio.h>
11 #include <kernel/dt_driver.h>
12 #include <stdint.h>
13 #include <tee_api_types.h>
14
15 /**
16 * GPIO_DT_DECLARE - Declare a GPIO controller driver with a single
17 * device tree compatible string.
18 *
19 * @__name: GPIO controller driver name
20 * @__compat: Compatible string
21 * @__probe: GPIO controller probe function
22 */
23 #define GPIO_DT_DECLARE(__name, __compat, __probe) \
24 static const struct dt_device_match __name ## _match_table[] = { \
25 { .compatible = __compat }, \
26 { } \
27 }; \
28 DEFINE_DT_DRIVER(__name ## _dt_driver) = { \
29 .name = # __name, \
30 .type = DT_DRIVER_GPIO, \
31 .match_table = __name ## _match_table, \
32 .probe = __probe, \
33 }
34
35 enum gpio_dir {
36 GPIO_DIR_OUT,
37 GPIO_DIR_IN
38 };
39
40 enum gpio_level {
41 GPIO_LEVEL_LOW,
42 GPIO_LEVEL_HIGH
43 };
44
45 enum gpio_interrupt {
46 GPIO_INTERRUPT_DISABLE,
47 GPIO_INTERRUPT_ENABLE
48 };
49
50 struct gpio;
51 struct gpio_ops;
52
53 struct gpio_chip {
54 const struct gpio_ops *ops;
55 };
56
57 struct gpio_ops {
58 /* Get GPIO direction current configuration */
59 enum gpio_dir (*get_direction)(struct gpio_chip *chip,
60 unsigned int gpio_pin);
61 /* Set GPIO direction configuration */
62 void (*set_direction)(struct gpio_chip *chip, unsigned int gpio_pin,
63 enum gpio_dir direction);
64 /* Get GPIO current level */
65 enum gpio_level (*get_value)(struct gpio_chip *chip,
66 unsigned int gpio_pin);
67 /* Set GPIO level */
68 void (*set_value)(struct gpio_chip *chip, unsigned int gpio_pin,
69 enum gpio_level value);
70 /* Get GPIO interrupt state */
71 enum gpio_interrupt (*get_interrupt)(struct gpio_chip *chip,
72 unsigned int gpio_pin);
73 /* Enable or disable a GPIO interrupt */
74 void (*set_interrupt)(struct gpio_chip *chip, unsigned int gpio_pin,
75 enum gpio_interrupt enable_disable);
76 /* Release GPIO resources */
77 void (*put)(struct gpio_chip *chip, struct gpio *gpio);
78 };
79
80 /*
81 * struct gpio - GPIO pin description
82 * @chip: GPIO controller chip reference
83 * @dt_flags: Pin boolean properties set from DT node
84 * @pin: Pin number in GPIO controller
85 */
86 struct gpio {
87 struct gpio_chip *chip;
88 uint32_t dt_flags;
89 unsigned int pin;
90 };
91
gpio_ops_is_valid(const struct gpio_ops * ops)92 static inline bool gpio_ops_is_valid(const struct gpio_ops *ops)
93 {
94 return ops->set_direction && ops->get_direction && ops->get_value &&
95 ops->set_value;
96 }
97
gpio_set_direction(struct gpio * gpio,enum gpio_dir dir)98 static inline void gpio_set_direction(struct gpio *gpio, enum gpio_dir dir)
99 {
100 gpio->chip->ops->set_direction(gpio->chip, gpio->pin, dir);
101 }
102
gpio_get_direction(struct gpio * gpio)103 static inline enum gpio_dir gpio_get_direction(struct gpio *gpio)
104 {
105 return gpio->chip->ops->get_direction(gpio->chip, gpio->pin);
106 }
107
gpio_set_value(struct gpio * gpio,enum gpio_level value)108 static inline void gpio_set_value(struct gpio *gpio, enum gpio_level value)
109 {
110 if (gpio->dt_flags & GPIO_ACTIVE_LOW)
111 value = !value;
112
113 gpio->chip->ops->set_value(gpio->chip, gpio->pin, value);
114 }
115
gpio_get_value(struct gpio * gpio)116 static inline enum gpio_level gpio_get_value(struct gpio *gpio)
117 {
118 enum gpio_level value = GPIO_LEVEL_LOW;
119
120 value = gpio->chip->ops->get_value(gpio->chip, gpio->pin);
121
122 if (gpio->dt_flags & GPIO_ACTIVE_LOW)
123 value = !value;
124
125 return value;
126 }
127
gpio_put(struct gpio * gpio)128 static inline void gpio_put(struct gpio *gpio)
129 {
130 assert(!gpio || (gpio->chip && gpio->chip->ops));
131
132 if (gpio && gpio->chip->ops->put)
133 gpio->chip->ops->put(gpio->chip, gpio);
134 }
135
136 #if defined(CFG_DT) && defined(CFG_DRIVERS_GPIO)
137 /**
138 * gpio_dt_alloc_pin() - Get an allocated GPIO instance from its DT phandle
139 *
140 * @pargs: Pointer to devicetree description of the GPIO controller to parse
141 * @res: Output result code of the operation:
142 * TEE_SUCCESS in case of success
143 * TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized
144 * Any TEE_Result compliant code in case of error.
145 *
146 * Returns a struct gpio pointer pointing to a GPIO instance matching
147 * the devicetree description or NULL if invalid description in which case
148 * @res provides the error code.
149 */
150 TEE_Result gpio_dt_alloc_pin(struct dt_pargs *pargs, struct gpio **gpio);
151
152 /**
153 * gpio_dt_get_by_index() - Get a GPIO controller at a specific index in
154 * 'gpios' property
155 *
156 * @fdt: Device tree to work on
157 * @nodeoffset: Node offset of the subnode containing a 'gpios' property
158 * @index: GPIO pin index in '*-gpios' property
159 * @gpio_name: Name of the GPIO pin
160 * @gpio: Output GPIO pin reference upon success
161 *
162 * Return TEE_SUCCESS in case of success
163 * Return TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized
164 * Return a TEE_Result compliant code in case of error
165 */
166 TEE_Result gpio_dt_get_by_index(const void *fdt, int nodeoffset,
167 unsigned int index, const char *gpio_name,
168 struct gpio **gpio);
169 #else
gpio_dt_get_by_index(const void * fdt __unused,int nodeoffset __unused,unsigned int index __unused,const char * gpio_name __unused,struct gpio ** gpio __unused)170 static inline TEE_Result gpio_dt_get_by_index(const void *fdt __unused,
171 int nodeoffset __unused,
172 unsigned int index __unused,
173 const char *gpio_name __unused,
174 struct gpio **gpio __unused)
175 {
176 return TEE_ERROR_NOT_SUPPORTED;
177 }
178
gpio_dt_alloc_pin(struct dt_pargs * pargs __unused,struct gpio ** gpio __unused)179 static inline TEE_Result gpio_dt_alloc_pin(struct dt_pargs *pargs __unused,
180 struct gpio **gpio __unused)
181 {
182 return TEE_ERROR_NOT_SUPPORTED;
183 }
184 #endif /*CFG_DT*/
185
186 /**
187 * gpio_dt_get_func - Typedef of function to get GPIO instance from
188 * devicetree properties
189 *
190 * @pargs: Pointer to GPIO phandle and its argument in the FDT
191 * @data: Pointer to the data given at gpio_dt_register_provider() call
192 * @res: Output result code of the operation:
193 * TEE_SUCCESS in case of success
194 * TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized
195 * Any TEE_Result compliant code in case of error.
196 *
197 * Returns a struct GPIO pointer pointing to a GPIO instance matching
198 * the devicetree description or NULL if invalid description in which case
199 * @res provides the error code.
200 */
201 typedef TEE_Result (*gpio_dt_get_func)(struct dt_pargs *pargs, void *data,
202 struct gpio **out_gpio);
203
204 /**
205 * gpio_dt_register_provider() - Register a GPIO controller provider
206 *
207 * @fdt: Device tree to work on
208 * @nodeoffset: Node offset of the GPIO controller
209 * @get_dt_gpio: Callback to match the GPIO controller with a struct gpio
210 * @data: Opaque reference which will be passed to the get_dt_gpio callback
211 * Returns TEE_Result value
212 */
gpio_register_provider(const void * fdt,int nodeoffset,gpio_dt_get_func get_dt_gpio,void * data)213 static inline TEE_Result gpio_register_provider(const void *fdt, int nodeoffset,
214 gpio_dt_get_func get_dt_gpio,
215 void *data)
216 {
217 return dt_driver_register_provider(fdt, nodeoffset,
218 (get_of_device_func)get_dt_gpio,
219 data, DT_DRIVER_GPIO);
220 }
221
222 #endif /* __DRIVERS_GPIO_H */
223