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