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 #define GPIO_FLAGS_BIT_DIR_SET BIT(0) 36 #define GPIO_FLAGS_BIT_DIR_OUT BIT(1) 37 #define GPIO_FLAGS_BIT_DIR_VAL BIT(2) 38 39 /** 40 * enum gpio_flags - Optional flags that are used to configure direction and 41 * output value. These values cannot be OR'd. 42 * 43 * @GPIOD_ASIS: Don't change anything 44 * @GPIO_IN: Set line to input mode 45 * @GPIO_OUT_LOW: Set line to output and drive it low 46 * @GPIO_OUT_HIGH: Set line to output and drive it high 47 48 */ 49 enum gpio_flags { 50 GPIO_ASIS = 0, 51 GPIO_IN = GPIO_FLAGS_BIT_DIR_SET, 52 GPIO_OUT_LOW = GPIO_FLAGS_BIT_DIR_SET | GPIO_FLAGS_BIT_DIR_OUT, 53 GPIO_OUT_HIGH = GPIO_FLAGS_BIT_DIR_SET | GPIO_FLAGS_BIT_DIR_OUT | 54 GPIO_FLAGS_BIT_DIR_VAL, 55 }; 56 57 enum gpio_dir { 58 GPIO_DIR_OUT, 59 GPIO_DIR_IN 60 }; 61 62 enum gpio_level { 63 GPIO_LEVEL_LOW, 64 GPIO_LEVEL_HIGH 65 }; 66 67 enum gpio_interrupt { 68 GPIO_INTERRUPT_DISABLE, 69 GPIO_INTERRUPT_ENABLE 70 }; 71 72 struct gpio; 73 struct gpio_ops; 74 75 struct gpio_chip { 76 const struct gpio_ops *ops; 77 }; 78 79 struct gpio_ops { 80 /* Get GPIO direction current configuration */ 81 enum gpio_dir (*get_direction)(struct gpio_chip *chip, 82 unsigned int gpio_pin); 83 /* Set GPIO direction configuration */ 84 void (*set_direction)(struct gpio_chip *chip, unsigned int gpio_pin, 85 enum gpio_dir direction); 86 /* Get GPIO current level */ 87 enum gpio_level (*get_value)(struct gpio_chip *chip, 88 unsigned int gpio_pin); 89 /* Set GPIO level */ 90 void (*set_value)(struct gpio_chip *chip, unsigned int gpio_pin, 91 enum gpio_level value); 92 /* Get GPIO interrupt state */ 93 enum gpio_interrupt (*get_interrupt)(struct gpio_chip *chip, 94 unsigned int gpio_pin); 95 /* Enable or disable a GPIO interrupt */ 96 void (*set_interrupt)(struct gpio_chip *chip, unsigned int gpio_pin, 97 enum gpio_interrupt enable_disable); 98 /* Release GPIO resources */ 99 void (*put)(struct gpio_chip *chip, struct gpio *gpio); 100 }; 101 102 /* 103 * struct gpio - GPIO pin description 104 * @chip: GPIO controller chip reference 105 * @dt_flags: Pin boolean properties set from DT node 106 * @pin: Pin number in GPIO controller 107 */ 108 struct gpio { 109 struct gpio_chip *chip; 110 uint32_t dt_flags; 111 unsigned int pin; 112 }; 113 114 static inline bool gpio_ops_is_valid(const struct gpio_ops *ops) 115 { 116 return ops->set_direction && ops->get_direction && ops->get_value && 117 ops->set_value; 118 } 119 120 static inline void gpio_set_direction(struct gpio *gpio, enum gpio_dir dir) 121 { 122 gpio->chip->ops->set_direction(gpio->chip, gpio->pin, dir); 123 } 124 125 static inline enum gpio_dir gpio_get_direction(struct gpio *gpio) 126 { 127 return gpio->chip->ops->get_direction(gpio->chip, gpio->pin); 128 } 129 130 static inline void gpio_set_value(struct gpio *gpio, enum gpio_level value) 131 { 132 if (gpio->dt_flags & GPIO_ACTIVE_LOW) 133 value = !value; 134 135 gpio->chip->ops->set_value(gpio->chip, gpio->pin, value); 136 } 137 138 static inline enum gpio_level gpio_get_value(struct gpio *gpio) 139 { 140 enum gpio_level value = GPIO_LEVEL_LOW; 141 142 value = gpio->chip->ops->get_value(gpio->chip, gpio->pin); 143 144 if (gpio->dt_flags & GPIO_ACTIVE_LOW) 145 value = !value; 146 147 return value; 148 } 149 150 static inline void gpio_put(struct gpio *gpio) 151 { 152 assert(!gpio || (gpio->chip && gpio->chip->ops)); 153 154 if (gpio && gpio->chip->ops->put) 155 gpio->chip->ops->put(gpio->chip, gpio); 156 } 157 158 /** 159 * gpio_configure() - Configure a GPIO controller 160 * 161 * @gpio: GPIO pin 162 * @flags: requester flags of GPIO 163 * 164 * Return TEE_SUCCESS in case of success 165 * Return a TEE_Result compliant code in case of error 166 */ 167 TEE_Result gpio_configure(struct gpio *gpio, enum gpio_flags flags); 168 169 #if defined(CFG_DT) && defined(CFG_DRIVERS_GPIO) 170 /** 171 * gpio_dt_alloc_pin() - Get an allocated GPIO instance from its DT phandle 172 * 173 * @pargs: Pointer to devicetree description of the GPIO controller to parse 174 * @res: Output result code of the operation: 175 * TEE_SUCCESS in case of success 176 * TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized 177 * Any TEE_Result compliant code in case of error. 178 * 179 * Returns a struct gpio pointer pointing to a GPIO instance matching 180 * the devicetree description or NULL if invalid description in which case 181 * @res provides the error code. 182 */ 183 TEE_Result gpio_dt_alloc_pin(struct dt_pargs *pargs, struct gpio **gpio); 184 185 /** 186 * gpio_dt_get_by_index() - Get a GPIO controller at a specific index in 187 * 'gpios' or 'gpio' properties with or without prefixes. 188 * 189 * @fdt: Device tree to work on 190 * @nodeoffset: Node offset of the subnode containing a 'gpios' or 'gpio' 191 * property. 192 * @index: GPIO pin index in 'gpios' property find in device tree. 193 * @gpio_name: Prefix of a '-gpios' or '-gpio' properties in device tree, 194 * can be NULL to search for 'gpios' or 'gpio' properties 195 * @gpio: Output GPIO pin reference upon success 196 * 197 * Return TEE_SUCCESS in case of success 198 * Return TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized 199 * Return a TEE_Result compliant code in case of error 200 */ 201 TEE_Result gpio_dt_get_by_index(const void *fdt, int nodeoffset, 202 unsigned int index, const char *gpio_name, 203 struct gpio **gpio); 204 205 /** 206 * gpio_dt_cfg_by_index() - Get a GPIO controller at a specific index in 207 * 'gpios' or 'gpio' properties (possibly prefixed) and configure it with 208 * flags. 209 * 210 * @fdt: Device tree to work on 211 * @nodeoffset: Node offset of the subnode containing a 'gpios' or 'gpio' 212 * property. 213 * @index: GPIO pin index in 'gpios' property to get in device tree. 214 * @gpio_name: Prefix of a '-gpios' or '-gpio' properties in device tree, 215 * can be NULL to search for 'gpios' or 'gpio' properties 216 * @flags: Configuration flags for the GPIO 217 * @gpio: Output GPIO pin reference upon success 218 * 219 * Return TEE_SUCCESS in case of success 220 * Return TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized 221 * Return a TEE_Result compliant code in case of error 222 */ 223 TEE_Result gpio_dt_cfg_by_index(const void *fdt, int nodeoffset, 224 unsigned int index, const char *gpio_name, 225 enum gpio_flags flags, struct gpio **gpio); 226 #else 227 static inline TEE_Result gpio_dt_get_by_index(const void *fdt __unused, 228 int nodeoffset __unused, 229 unsigned int index __unused, 230 const char *gpio_name __unused, 231 struct gpio **gpio __unused) 232 { 233 return TEE_ERROR_NOT_SUPPORTED; 234 } 235 236 static inline TEE_Result gpio_dt_cfg_by_index(const void *fdt __unused, 237 int nodeoffset __unused, 238 unsigned int index __unused, 239 const char *gpio_name __unused, 240 enum gpio_flags flags __unused, 241 struct gpio **gpio __unused) 242 { 243 return TEE_ERROR_NOT_SUPPORTED; 244 } 245 246 static inline TEE_Result gpio_dt_alloc_pin(struct dt_pargs *pargs __unused, 247 struct gpio **gpio __unused) 248 { 249 return TEE_ERROR_NOT_SUPPORTED; 250 } 251 #endif /*CFG_DT*/ 252 253 /** 254 * gpio_dt_get_func - Typedef of function to get GPIO instance from 255 * devicetree properties 256 * 257 * @pargs: Pointer to GPIO phandle and its argument in the FDT 258 * @data: Pointer to the data given at gpio_dt_register_provider() call 259 * @res: Output result code of the operation: 260 * TEE_SUCCESS in case of success 261 * TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized 262 * Any TEE_Result compliant code in case of error. 263 * 264 * Returns a struct GPIO pointer pointing to a GPIO instance matching 265 * the devicetree description or NULL if invalid description in which case 266 * @res provides the error code. 267 */ 268 typedef TEE_Result (*gpio_dt_get_func)(struct dt_pargs *pargs, void *data, 269 struct gpio **out_gpio); 270 271 /** 272 * gpio_dt_register_provider() - Register a GPIO controller provider 273 * 274 * @fdt: Device tree to work on 275 * @nodeoffset: Node offset of the GPIO controller 276 * @get_dt_gpio: Callback to match the GPIO controller with a struct gpio 277 * @data: Opaque reference which will be passed to the get_dt_gpio callback 278 * Returns TEE_Result value 279 */ 280 static inline TEE_Result gpio_register_provider(const void *fdt, int nodeoffset, 281 gpio_dt_get_func get_dt_gpio, 282 void *data) 283 { 284 return dt_driver_register_provider(fdt, nodeoffset, 285 (get_of_device_func)get_dt_gpio, 286 data, DT_DRIVER_GPIO); 287 } 288 289 #endif /* __DRIVERS_GPIO_H */ 290