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 /* Configure GPIO resources, based on dt_flags */ 99 TEE_Result (*configure)(struct gpio_chip *chip, struct gpio *gpio); 100 /* Release GPIO resources */ 101 void (*put)(struct gpio_chip *chip, struct gpio *gpio); 102 }; 103 104 /* 105 * struct gpio - GPIO pin description 106 * @chip: GPIO controller chip reference 107 * @dt_flags: Pin boolean properties set from DT node 108 * @pin: Pin number in GPIO controller 109 */ 110 struct gpio { 111 struct gpio_chip *chip; 112 uint32_t dt_flags; 113 unsigned int pin; 114 }; 115 116 static inline bool gpio_ops_is_valid(const struct gpio_ops *ops) 117 { 118 return ops->set_direction && ops->get_direction && ops->get_value && 119 ops->set_value; 120 } 121 122 static inline void gpio_set_direction(struct gpio *gpio, enum gpio_dir dir) 123 { 124 gpio->chip->ops->set_direction(gpio->chip, gpio->pin, dir); 125 } 126 127 static inline enum gpio_dir gpio_get_direction(struct gpio *gpio) 128 { 129 return gpio->chip->ops->get_direction(gpio->chip, gpio->pin); 130 } 131 132 static inline void gpio_set_value(struct gpio *gpio, enum gpio_level value) 133 { 134 if (gpio->dt_flags & GPIO_ACTIVE_LOW) 135 value = !value; 136 137 gpio->chip->ops->set_value(gpio->chip, gpio->pin, value); 138 } 139 140 static inline enum gpio_level gpio_get_value(struct gpio *gpio) 141 { 142 enum gpio_level value = GPIO_LEVEL_LOW; 143 144 value = gpio->chip->ops->get_value(gpio->chip, gpio->pin); 145 146 if (gpio->dt_flags & GPIO_ACTIVE_LOW) 147 value = !value; 148 149 return value; 150 } 151 152 static inline void gpio_put(struct gpio *gpio) 153 { 154 assert(!gpio || (gpio->chip && gpio->chip->ops)); 155 156 if (gpio && gpio->chip->ops->put) 157 gpio->chip->ops->put(gpio->chip, gpio); 158 } 159 160 /** 161 * gpio_configure() - Configure a GPIO controller 162 * 163 * @gpio: GPIO pin 164 * @flags: requester flags of GPIO 165 * 166 * Return TEE_SUCCESS in case of success 167 * Return a TEE_Result compliant code in case of error 168 */ 169 TEE_Result gpio_configure(struct gpio *gpio, enum gpio_flags flags); 170 171 #if defined(CFG_DT) && defined(CFG_DRIVERS_GPIO) 172 /** 173 * gpio_dt_alloc_pin() - Get an allocated GPIO instance from its DT phandle 174 * 175 * @pargs: Pointer to devicetree description of the GPIO controller to parse 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 TEE_Result gpio_dt_alloc_pin(struct dt_pargs *pargs, struct gpio **gpio); 186 187 /** 188 * gpio_dt_get_by_index() - Get a GPIO controller at a specific index in 189 * 'gpios' or 'gpio' properties with or without prefixes. 190 * 191 * @fdt: Device tree to work on 192 * @nodeoffset: Node offset of the subnode containing a 'gpios' or 'gpio' 193 * property. 194 * @index: GPIO pin index in 'gpios' property find in device tree. 195 * @gpio_name: Prefix of a '-gpios' or '-gpio' properties in device tree, 196 * can be NULL to search for 'gpios' or 'gpio' properties 197 * @gpio: Output GPIO pin reference upon success 198 * 199 * Return TEE_SUCCESS in case of success 200 * Return TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized 201 * Return a TEE_Result compliant code in case of error 202 */ 203 TEE_Result gpio_dt_get_by_index(const void *fdt, int nodeoffset, 204 unsigned int index, const char *gpio_name, 205 struct gpio **gpio); 206 207 /** 208 * gpio_dt_cfg_by_index() - Get a GPIO controller at a specific index in 209 * 'gpios' or 'gpio' properties (possibly prefixed) and configure it with 210 * flags. 211 * 212 * @fdt: Device tree to work on 213 * @nodeoffset: Node offset of the subnode containing a 'gpios' or 'gpio' 214 * property. 215 * @index: GPIO pin index in 'gpios' property to get in device tree. 216 * @gpio_name: Prefix of a '-gpios' or '-gpio' properties in device tree, 217 * can be NULL to search for 'gpios' or 'gpio' properties 218 * @flags: Configuration flags for the GPIO 219 * @gpio: Output GPIO pin reference upon success 220 * 221 * Return TEE_SUCCESS in case of success 222 * Return TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized 223 * Return a TEE_Result compliant code in case of error 224 */ 225 TEE_Result gpio_dt_cfg_by_index(const void *fdt, int nodeoffset, 226 unsigned int index, const char *gpio_name, 227 enum gpio_flags flags, struct gpio **gpio); 228 #else 229 static inline TEE_Result gpio_dt_get_by_index(const void *fdt __unused, 230 int nodeoffset __unused, 231 unsigned int index __unused, 232 const char *gpio_name __unused, 233 struct gpio **gpio __unused) 234 { 235 return TEE_ERROR_NOT_SUPPORTED; 236 } 237 238 static inline TEE_Result gpio_dt_cfg_by_index(const void *fdt __unused, 239 int nodeoffset __unused, 240 unsigned int index __unused, 241 const char *gpio_name __unused, 242 enum gpio_flags flags __unused, 243 struct gpio **gpio __unused) 244 { 245 return TEE_ERROR_NOT_SUPPORTED; 246 } 247 248 static inline TEE_Result gpio_dt_alloc_pin(struct dt_pargs *pargs __unused, 249 struct gpio **gpio __unused) 250 { 251 return TEE_ERROR_NOT_SUPPORTED; 252 } 253 #endif /*CFG_DT*/ 254 255 /** 256 * gpio_dt_get_func - Typedef of function to get GPIO instance from 257 * devicetree properties 258 * 259 * @pargs: Pointer to GPIO phandle and its argument in the FDT 260 * @data: Pointer to the data given at gpio_dt_register_provider() call 261 * @res: Output result code of the operation: 262 * TEE_SUCCESS in case of success 263 * TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized 264 * Any TEE_Result compliant code in case of error. 265 * 266 * Returns a struct GPIO pointer pointing to a GPIO instance matching 267 * the devicetree description or NULL if invalid description in which case 268 * @res provides the error code. 269 */ 270 typedef TEE_Result (*gpio_dt_get_func)(struct dt_pargs *pargs, void *data, 271 struct gpio **out_gpio); 272 273 /** 274 * gpio_dt_register_provider() - Register a GPIO controller provider 275 * 276 * @fdt: Device tree to work on 277 * @nodeoffset: Node offset of the GPIO controller 278 * @get_dt_gpio: Callback to match the GPIO controller with a struct gpio 279 * @data: Opaque reference which will be passed to the get_dt_gpio callback 280 * Returns TEE_Result value 281 */ 282 static inline TEE_Result gpio_register_provider(const void *fdt, int nodeoffset, 283 gpio_dt_get_func get_dt_gpio, 284 void *data) 285 { 286 return dt_driver_register_provider(fdt, nodeoffset, 287 (get_of_device_func)get_dt_gpio, 288 data, DT_DRIVER_GPIO); 289 } 290 291 #endif /* __DRIVERS_GPIO_H */ 292