16dcd18c8SClément Léger /* SPDX-License-Identifier: BSD-2-Clause */ 26dcd18c8SClément Léger /* 36dcd18c8SClément Léger * Copyright (c) 2016, Linaro Limited 46dcd18c8SClément Léger */ 56dcd18c8SClément Léger 66dcd18c8SClément Léger #ifndef DRIVERS_GPIO_H 76dcd18c8SClément Léger #define DRIVERS_GPIO_H 86dcd18c8SClément Léger 9*4fc179b6SThomas Perrot #include <dt-bindings/gpio/gpio.h> 10*4fc179b6SThomas Perrot #include <kernel/dt_driver.h> 11*4fc179b6SThomas Perrot #include <stdint.h> 12*4fc179b6SThomas Perrot #include <tee_api_types.h> 13*4fc179b6SThomas Perrot 14*4fc179b6SThomas Perrot /** 15*4fc179b6SThomas Perrot * GPIO_DT_DECLARE - Declare a GPIO controller driver with a single 16*4fc179b6SThomas Perrot * device tree compatible string. 17*4fc179b6SThomas Perrot * 18*4fc179b6SThomas Perrot * @__name: GPIO controller driver name 19*4fc179b6SThomas Perrot * @__compat: Compatible string 20*4fc179b6SThomas Perrot * @__probe: GPIO controller probe function 21*4fc179b6SThomas Perrot */ 22*4fc179b6SThomas Perrot #define GPIO_DT_DECLARE(__name, __compat, __probe) \ 23*4fc179b6SThomas Perrot static const struct dt_device_match __name ## _match_table[] = { \ 24*4fc179b6SThomas Perrot { .compatible = __compat }, \ 25*4fc179b6SThomas Perrot { } \ 26*4fc179b6SThomas Perrot }; \ 27*4fc179b6SThomas Perrot DEFINE_DT_DRIVER(__name ## _dt_driver) = { \ 28*4fc179b6SThomas Perrot .name = # __name, \ 29*4fc179b6SThomas Perrot .type = DT_DRIVER_GPIO, \ 30*4fc179b6SThomas Perrot .match_table = __name ## _match_table, \ 31*4fc179b6SThomas Perrot .probe = __probe, \ 32*4fc179b6SThomas Perrot } 33*4fc179b6SThomas Perrot 346dcd18c8SClément Léger enum gpio_dir { 356dcd18c8SClément Léger GPIO_DIR_OUT, 366dcd18c8SClément Léger GPIO_DIR_IN 376dcd18c8SClément Léger }; 386dcd18c8SClément Léger 396dcd18c8SClément Léger enum gpio_level { 406dcd18c8SClément Léger GPIO_LEVEL_LOW, 416dcd18c8SClément Léger GPIO_LEVEL_HIGH 426dcd18c8SClément Léger }; 436dcd18c8SClément Léger 446dcd18c8SClément Léger enum gpio_interrupt { 456dcd18c8SClément Léger GPIO_INTERRUPT_DISABLE, 466dcd18c8SClément Léger GPIO_INTERRUPT_ENABLE 476dcd18c8SClément Léger }; 486dcd18c8SClément Léger 496dcd18c8SClément Léger struct gpio_chip { 506dcd18c8SClément Léger const struct gpio_ops *ops; 516dcd18c8SClément Léger }; 526dcd18c8SClément Léger 536dcd18c8SClément Léger struct gpio_ops { 546dcd18c8SClément Léger enum gpio_dir (*get_direction)(struct gpio_chip *chip, 556dcd18c8SClément Léger unsigned int gpio_pin); 566dcd18c8SClément Léger void (*set_direction)(struct gpio_chip *chip, unsigned int gpio_pin, 576dcd18c8SClément Léger enum gpio_dir direction); 586dcd18c8SClément Léger enum gpio_level (*get_value)(struct gpio_chip *chip, 596dcd18c8SClément Léger unsigned int gpio_pin); 606dcd18c8SClément Léger void (*set_value)(struct gpio_chip *chip, unsigned int gpio_pin, 616dcd18c8SClément Léger enum gpio_level value); 626dcd18c8SClément Léger enum gpio_interrupt (*get_interrupt)(struct gpio_chip *chip, 636dcd18c8SClément Léger unsigned int gpio_pin); 646dcd18c8SClément Léger void (*set_interrupt)(struct gpio_chip *chip, unsigned int gpio_pin, 656dcd18c8SClément Léger enum gpio_interrupt enable_disable); 666dcd18c8SClément Léger }; 676dcd18c8SClément Léger 68*4fc179b6SThomas Perrot /* 69*4fc179b6SThomas Perrot * struct gpio - GPIO pin description 70*4fc179b6SThomas Perrot * @chip: GPIO controller chip reference 71*4fc179b6SThomas Perrot * @dt_flags: Pin boolean properties set from DT node 72*4fc179b6SThomas Perrot * @pin: Pin number in GPIO controller 73*4fc179b6SThomas Perrot */ 74*4fc179b6SThomas Perrot struct gpio { 75*4fc179b6SThomas Perrot struct gpio_chip *chip; 76*4fc179b6SThomas Perrot uint32_t dt_flags; 77*4fc179b6SThomas Perrot unsigned int pin; 78*4fc179b6SThomas Perrot }; 79*4fc179b6SThomas Perrot 80*4fc179b6SThomas Perrot static inline bool gpio_ops_is_valid(const struct gpio_ops *ops) 81*4fc179b6SThomas Perrot { 82*4fc179b6SThomas Perrot return ops->set_direction && ops->get_direction && ops->get_value && 83*4fc179b6SThomas Perrot ops->set_value; 84*4fc179b6SThomas Perrot } 85*4fc179b6SThomas Perrot 86*4fc179b6SThomas Perrot static inline void gpio_set_direction(struct gpio *gpio, enum gpio_dir dir) 87*4fc179b6SThomas Perrot { 88*4fc179b6SThomas Perrot gpio->chip->ops->set_direction(gpio->chip, gpio->pin, dir); 89*4fc179b6SThomas Perrot } 90*4fc179b6SThomas Perrot 91*4fc179b6SThomas Perrot static inline enum gpio_dir gpio_get_direction(struct gpio *gpio) 92*4fc179b6SThomas Perrot { 93*4fc179b6SThomas Perrot return gpio->chip->ops->get_direction(gpio->chip, gpio->pin); 94*4fc179b6SThomas Perrot } 95*4fc179b6SThomas Perrot 96*4fc179b6SThomas Perrot static inline void gpio_set_value(struct gpio *gpio, enum gpio_level value) 97*4fc179b6SThomas Perrot { 98*4fc179b6SThomas Perrot if (gpio->dt_flags & GPIO_ACTIVE_LOW) 99*4fc179b6SThomas Perrot value = !value; 100*4fc179b6SThomas Perrot 101*4fc179b6SThomas Perrot gpio->chip->ops->set_value(gpio->chip, gpio->pin, value); 102*4fc179b6SThomas Perrot } 103*4fc179b6SThomas Perrot 104*4fc179b6SThomas Perrot static inline enum gpio_level gpio_get_value(struct gpio *gpio) 105*4fc179b6SThomas Perrot { 106*4fc179b6SThomas Perrot enum gpio_level value = GPIO_LEVEL_LOW; 107*4fc179b6SThomas Perrot 108*4fc179b6SThomas Perrot value = gpio->chip->ops->get_value(gpio->chip, gpio->pin); 109*4fc179b6SThomas Perrot 110*4fc179b6SThomas Perrot if (gpio->dt_flags & GPIO_ACTIVE_LOW) 111*4fc179b6SThomas Perrot value = !value; 112*4fc179b6SThomas Perrot 113*4fc179b6SThomas Perrot return value; 114*4fc179b6SThomas Perrot } 115*4fc179b6SThomas Perrot 116*4fc179b6SThomas Perrot #if defined(CFG_DT) && defined(CFG_DRIVERS_GPIO) 117*4fc179b6SThomas Perrot /** 118*4fc179b6SThomas Perrot * gpio_dt_alloc_pin() - Get an allocated GPIO instance from its DT phandle 119*4fc179b6SThomas Perrot * 120*4fc179b6SThomas Perrot * @a: Pointer to devicetree description of the GPIO controller to parse 121*4fc179b6SThomas Perrot * @res: Output result code of the operation: 122*4fc179b6SThomas Perrot * TEE_SUCCESS in case of success 123*4fc179b6SThomas Perrot * TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized 124*4fc179b6SThomas Perrot * Any TEE_Result compliant code in case of error. 125*4fc179b6SThomas Perrot * 126*4fc179b6SThomas Perrot * Returns a struct gpio pointer pointing to a GPIO instance matching 127*4fc179b6SThomas Perrot * the devicetree description or NULL if invalid description in which case 128*4fc179b6SThomas Perrot * @res provides the error code. 129*4fc179b6SThomas Perrot */ 130*4fc179b6SThomas Perrot struct gpio *gpio_dt_alloc_pin(struct dt_driver_phandle_args *a, 131*4fc179b6SThomas Perrot TEE_Result *res); 132*4fc179b6SThomas Perrot 133*4fc179b6SThomas Perrot /** 134*4fc179b6SThomas Perrot * gpio_dt_get_by_index() - Get a GPIO controller at a specific index in 135*4fc179b6SThomas Perrot * 'gpios' property 136*4fc179b6SThomas Perrot * 137*4fc179b6SThomas Perrot * @fdt: Device tree to work on 138*4fc179b6SThomas Perrot * @nodeoffset: Node offset of the subnode containing a 'gpios' property 139*4fc179b6SThomas Perrot * @index: GPIO pin index in '*-gpios' property 140*4fc179b6SThomas Perrot * @gpio_name: Name of the GPIO pin 141*4fc179b6SThomas Perrot * @gpio: Output GPIO pin reference upon success 142*4fc179b6SThomas Perrot * 143*4fc179b6SThomas Perrot * Return TEE_SUCCESS in case of success 144*4fc179b6SThomas Perrot * Return TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized 145*4fc179b6SThomas Perrot * Return a TEE_Result compliant code in case of error 146*4fc179b6SThomas Perrot */ 147*4fc179b6SThomas Perrot TEE_Result gpio_dt_get_by_index(const void *fdt, int nodeoffset, 148*4fc179b6SThomas Perrot unsigned int index, const char *gpio_name, 149*4fc179b6SThomas Perrot struct gpio **gpio); 150*4fc179b6SThomas Perrot #else 151*4fc179b6SThomas Perrot static inline TEE_Result gpio_dt_get_by_index(const void *fdt __unused, 152*4fc179b6SThomas Perrot int nodeoffset __unused, 153*4fc179b6SThomas Perrot unsigned int index __unused, 154*4fc179b6SThomas Perrot const char *gpio_name __unused, 155*4fc179b6SThomas Perrot struct gpio **gpio) 156*4fc179b6SThomas Perrot { 157*4fc179b6SThomas Perrot *gpio = NULL; 158*4fc179b6SThomas Perrot return TEE_ERROR_NOT_SUPPORTED; 159*4fc179b6SThomas Perrot } 160*4fc179b6SThomas Perrot 161*4fc179b6SThomas Perrot static inline 162*4fc179b6SThomas Perrot struct gpio *gpio_dt_alloc_pin(struct dt_driver_phandle_args *a __unused, 163*4fc179b6SThomas Perrot TEE_Result *res) 164*4fc179b6SThomas Perrot { 165*4fc179b6SThomas Perrot *res = TEE_ERROR_NOT_SUPPORTED; 166*4fc179b6SThomas Perrot return NULL; 167*4fc179b6SThomas Perrot } 168*4fc179b6SThomas Perrot #endif /*CFG_DT*/ 169*4fc179b6SThomas Perrot 170*4fc179b6SThomas Perrot /** 171*4fc179b6SThomas Perrot * gpio_dt_get_func - Typedef of function to get GPIO instance from 172*4fc179b6SThomas Perrot * devicetree properties 173*4fc179b6SThomas Perrot * 174*4fc179b6SThomas Perrot * @a: Pointer to GPIO phandle and its argument in the FDT 175*4fc179b6SThomas Perrot * @data: Pointer to the data given at gpio_dt_register_provider() call 176*4fc179b6SThomas Perrot * @res: Output result code of the operation: 177*4fc179b6SThomas Perrot * TEE_SUCCESS in case of success 178*4fc179b6SThomas Perrot * TEE_ERROR_DEFER_DRIVER_INIT if GPIO controller is not initialized 179*4fc179b6SThomas Perrot * Any TEE_Result compliant code in case of error. 180*4fc179b6SThomas Perrot * 181*4fc179b6SThomas Perrot * Returns a struct GPIO pointer pointing to a GPIO instance matching 182*4fc179b6SThomas Perrot * the devicetree description or NULL if invalid description in which case 183*4fc179b6SThomas Perrot * @res provides the error code. 184*4fc179b6SThomas Perrot */ 185*4fc179b6SThomas Perrot typedef struct gpio *(*gpio_dt_get_func)(struct dt_driver_phandle_args *a, 186*4fc179b6SThomas Perrot void *data, TEE_Result *res); 187*4fc179b6SThomas Perrot 188*4fc179b6SThomas Perrot /** 189*4fc179b6SThomas Perrot * gpio_dt_register_provider() - Register a GPIO controller provider 190*4fc179b6SThomas Perrot * 191*4fc179b6SThomas Perrot * @fdt: Device tree to work on 192*4fc179b6SThomas Perrot * @nodeoffset: Node offset of the GPIO controller 193*4fc179b6SThomas Perrot * @get_dt_gpio: Callback to match the GPIO controller with a struct gpio 194*4fc179b6SThomas Perrot * @data: Opaque reference which will be passed to the get_dt_gpio callback 195*4fc179b6SThomas Perrot * Returns TEE_Result value 196*4fc179b6SThomas Perrot */ 197*4fc179b6SThomas Perrot static inline TEE_Result gpio_register_provider(const void *fdt, int nodeoffset, 198*4fc179b6SThomas Perrot gpio_dt_get_func get_dt_gpio, 199*4fc179b6SThomas Perrot void *data) 200*4fc179b6SThomas Perrot { 201*4fc179b6SThomas Perrot return dt_driver_register_provider(fdt, nodeoffset, 202*4fc179b6SThomas Perrot (get_of_device_func)get_dt_gpio, 203*4fc179b6SThomas Perrot data, DT_DRIVER_GPIO); 204*4fc179b6SThomas Perrot } 205*4fc179b6SThomas Perrot 2066dcd18c8SClément Léger #endif /* DRIVERS_GPIO_H */ 207