xref: /optee_os/core/include/drivers/gpio.h (revision 12fc37711783247b0d05fdc271ef007f4930767b)
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 
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 
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 
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 
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 
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 
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 struct gpio *gpio_dt_alloc_pin(struct dt_pargs *pargs, TEE_Result *res);
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
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)
175 {
176 	*gpio = NULL;
177 	return TEE_ERROR_NOT_SUPPORTED;
178 }
179 
180 static inline struct gpio *gpio_dt_alloc_pin(struct dt_pargs *pargs __unused,
181 					     TEE_Result *res)
182 {
183 	*res = TEE_ERROR_NOT_SUPPORTED;
184 	return NULL;
185 }
186 #endif /*CFG_DT*/
187 
188 /**
189  * gpio_dt_get_func - Typedef of function to get GPIO instance from
190  * devicetree properties
191  *
192  * @pargs: Pointer to GPIO phandle and its argument in the FDT
193  * @data: Pointer to the data given at gpio_dt_register_provider() call
194  * @res: Output result code of the operation:
195  *	TEE_SUCCESS in case of success
196  *	TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized
197  *	Any TEE_Result compliant code in case of error.
198  *
199  * Returns a struct GPIO pointer pointing to a GPIO instance matching
200  * the devicetree description or NULL if invalid description in which case
201  * @res provides the error code.
202  */
203 typedef struct gpio *(*gpio_dt_get_func)(struct dt_pargs *pargs, void *data,
204 					 TEE_Result *res);
205 
206 /**
207  * gpio_dt_register_provider() - Register a GPIO controller provider
208  *
209  * @fdt: Device tree to work on
210  * @nodeoffset: Node offset of the GPIO controller
211  * @get_dt_gpio: Callback to match the GPIO controller with a struct gpio
212  * @data: Opaque reference which will be passed to the get_dt_gpio callback
213  * Returns TEE_Result value
214  */
215 static inline TEE_Result gpio_register_provider(const void *fdt, int nodeoffset,
216 						gpio_dt_get_func get_dt_gpio,
217 						void *data)
218 {
219 	return dt_driver_register_provider(fdt, nodeoffset,
220 					   (get_of_device_func)get_dt_gpio,
221 					   data, DT_DRIVER_GPIO);
222 }
223 
224 #endif	/* DRIVERS_GPIO_H */
225