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