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