xref: /optee_os/core/include/drivers/gpio.h (revision 83f24981b3f0dc275d0006f0fb6d711fc67a896c)
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 	enum gpio_dir (*get_direction)(struct gpio_chip *chip,
59 				       unsigned int gpio_pin);
60 	void (*set_direction)(struct gpio_chip *chip, unsigned int gpio_pin,
61 			      enum gpio_dir direction);
62 	enum gpio_level (*get_value)(struct gpio_chip *chip,
63 				     unsigned int gpio_pin);
64 	void (*set_value)(struct gpio_chip *chip, unsigned int gpio_pin,
65 			  enum gpio_level value);
66 	enum gpio_interrupt (*get_interrupt)(struct gpio_chip *chip,
67 					     unsigned int gpio_pin);
68 	void (*set_interrupt)(struct gpio_chip *chip, unsigned int gpio_pin,
69 			      enum gpio_interrupt enable_disable);
70 	/* Release GPIO resources */
71 	void (*put)(struct gpio_chip *chip, struct gpio *gpio);
72 };
73 
74 /*
75  * struct gpio - GPIO pin description
76  * @chip: GPIO controller chip reference
77  * @dt_flags: Pin boolean properties set from DT node
78  * @pin: Pin number in GPIO controller
79  */
80 struct gpio {
81 	struct gpio_chip *chip;
82 	uint32_t dt_flags;
83 	unsigned int pin;
84 };
85 
86 static inline bool gpio_ops_is_valid(const struct gpio_ops *ops)
87 {
88 	return ops->set_direction && ops->get_direction && ops->get_value &&
89 	       ops->set_value;
90 }
91 
92 static inline void gpio_set_direction(struct gpio *gpio, enum gpio_dir dir)
93 {
94 	gpio->chip->ops->set_direction(gpio->chip, gpio->pin, dir);
95 }
96 
97 static inline enum gpio_dir gpio_get_direction(struct gpio *gpio)
98 {
99 	return gpio->chip->ops->get_direction(gpio->chip, gpio->pin);
100 }
101 
102 static inline void gpio_set_value(struct gpio *gpio, enum gpio_level value)
103 {
104 	if (gpio->dt_flags & GPIO_ACTIVE_LOW)
105 		value = !value;
106 
107 	gpio->chip->ops->set_value(gpio->chip, gpio->pin, value);
108 }
109 
110 static inline enum gpio_level gpio_get_value(struct gpio *gpio)
111 {
112 	enum gpio_level value = GPIO_LEVEL_LOW;
113 
114 	value = gpio->chip->ops->get_value(gpio->chip, gpio->pin);
115 
116 	if (gpio->dt_flags & GPIO_ACTIVE_LOW)
117 		value = !value;
118 
119 	return value;
120 }
121 
122 static inline void gpio_put(struct gpio *gpio)
123 {
124 	assert(!gpio || (gpio->chip && gpio->chip->ops));
125 
126 	if (gpio && gpio->chip->ops->put)
127 		gpio->chip->ops->put(gpio->chip, gpio);
128 }
129 
130 #if defined(CFG_DT) && defined(CFG_DRIVERS_GPIO)
131 /**
132  * gpio_dt_alloc_pin() - Get an allocated GPIO instance from its DT phandle
133  *
134  * @a: Pointer to devicetree description of the GPIO controller to parse
135  * @res: Output result code of the operation:
136  *	TEE_SUCCESS in case of success
137  *	TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized
138  *	Any TEE_Result compliant code in case of error.
139  *
140  * Returns a struct gpio pointer pointing to a GPIO instance matching
141  * the devicetree description or NULL if invalid description in which case
142  * @res provides the error code.
143  */
144 struct gpio *gpio_dt_alloc_pin(struct dt_driver_phandle_args *a,
145 			       TEE_Result *res);
146 
147 /**
148  * gpio_dt_get_by_index() - Get a GPIO controller at a specific index in
149  * 'gpios' property
150  *
151  * @fdt: Device tree to work on
152  * @nodeoffset: Node offset of the subnode containing a 'gpios' property
153  * @index: GPIO pin index in '*-gpios' property
154  * @gpio_name: Name of the GPIO pin
155  * @gpio: Output GPIO pin reference upon success
156  *
157  * Return TEE_SUCCESS in case of success
158  * Return TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized
159  * Return a TEE_Result compliant code in case of error
160  */
161 TEE_Result gpio_dt_get_by_index(const void *fdt, int nodeoffset,
162 				unsigned int index, const char *gpio_name,
163 				struct gpio **gpio);
164 #else
165 static inline TEE_Result gpio_dt_get_by_index(const void *fdt __unused,
166 					      int nodeoffset __unused,
167 					      unsigned int index  __unused,
168 					      const char *gpio_name  __unused,
169 					      struct gpio **gpio)
170 {
171 	*gpio = NULL;
172 	return TEE_ERROR_NOT_SUPPORTED;
173 }
174 
175 static inline
176 struct gpio *gpio_dt_alloc_pin(struct dt_driver_phandle_args *a __unused,
177 			       TEE_Result *res)
178 {
179 	*res = TEE_ERROR_NOT_SUPPORTED;
180 	return NULL;
181 }
182 #endif /*CFG_DT*/
183 
184 /**
185  * gpio_dt_get_func - Typedef of function to get GPIO instance from
186  * devicetree properties
187  *
188  * @a: Pointer to GPIO phandle and its argument in the FDT
189  * @data: Pointer to the data given at gpio_dt_register_provider() call
190  * @res: Output result code of the operation:
191  *	TEE_SUCCESS in case of success
192  *	TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized
193  *	Any TEE_Result compliant code in case of error.
194  *
195  * Returns a struct GPIO pointer pointing to a GPIO instance matching
196  * the devicetree description or NULL if invalid description in which case
197  * @res provides the error code.
198  */
199 typedef struct gpio *(*gpio_dt_get_func)(struct dt_driver_phandle_args *a,
200 					 void *data, TEE_Result *res);
201 
202 /**
203  * gpio_dt_register_provider() - Register a GPIO controller provider
204  *
205  * @fdt: Device tree to work on
206  * @nodeoffset: Node offset of the GPIO controller
207  * @get_dt_gpio: Callback to match the GPIO controller with a struct gpio
208  * @data: Opaque reference which will be passed to the get_dt_gpio callback
209  * Returns TEE_Result value
210  */
211 static inline TEE_Result gpio_register_provider(const void *fdt, int nodeoffset,
212 						gpio_dt_get_func get_dt_gpio,
213 						void *data)
214 {
215 	return dt_driver_register_provider(fdt, nodeoffset,
216 					   (get_of_device_func)get_dt_gpio,
217 					   data, DT_DRIVER_GPIO);
218 }
219 
220 #endif	/* DRIVERS_GPIO_H */
221