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