14fc179b6SThomas Perrot // SPDX-License-Identifier: BSD-2-Clause 24fc179b6SThomas Perrot /* 34fc179b6SThomas Perrot * Copyright (c) 2022, Microchip 44fc179b6SThomas Perrot */ 54fc179b6SThomas Perrot 64fc179b6SThomas Perrot #include <drivers/gpio.h> 74fc179b6SThomas Perrot #include <libfdt.h> 84fc179b6SThomas Perrot #include <stdio.h> 94fc179b6SThomas Perrot #include <tee_api_defines.h> 104fc179b6SThomas Perrot #include <tee_api_types.h> 114fc179b6SThomas Perrot #include <util.h> 124fc179b6SThomas Perrot 13*a37f67edSPatrick Delaunay /* gpio suffixes used for device tree lookup */ 14*a37f67edSPatrick Delaunay static const char * const gpio_suffixes[] = { "gpios", "gpio" }; 15*a37f67edSPatrick Delaunay 16b357d34fSEtienne Carriere TEE_Result gpio_dt_alloc_pin(struct dt_pargs *pargs, struct gpio **out_gpio) 174fc179b6SThomas Perrot { 184fc179b6SThomas Perrot struct gpio *gpio = NULL; 194fc179b6SThomas Perrot 20b357d34fSEtienne Carriere if (pargs->args_count != 2) 21b357d34fSEtienne Carriere return TEE_ERROR_BAD_PARAMETERS; 224fc179b6SThomas Perrot 234fc179b6SThomas Perrot gpio = calloc(1, sizeof(struct gpio)); 24b357d34fSEtienne Carriere if (!gpio) 25b357d34fSEtienne Carriere return TEE_ERROR_OUT_OF_MEMORY; 264fc179b6SThomas Perrot 278fd620f7SEtienne Carriere gpio->pin = pargs->args[0]; 288fd620f7SEtienne Carriere gpio->dt_flags = pargs->args[1]; 294fc179b6SThomas Perrot 30b357d34fSEtienne Carriere *out_gpio = gpio; 31b357d34fSEtienne Carriere 32b357d34fSEtienne Carriere return TEE_SUCCESS; 334fc179b6SThomas Perrot } 344fc179b6SThomas Perrot 354fc179b6SThomas Perrot TEE_Result gpio_dt_get_by_index(const void *fdt, int nodeoffset, 364fc179b6SThomas Perrot unsigned int index, const char *gpio_name, 374fc179b6SThomas Perrot struct gpio **gpio) 384fc179b6SThomas Perrot { 394fc179b6SThomas Perrot TEE_Result res = TEE_ERROR_GENERIC; 40*a37f67edSPatrick Delaunay char prop_name[32]; /* 32 is max size of property name in DT */ 41b357d34fSEtienne Carriere void *out_gpio = NULL; 42*a37f67edSPatrick Delaunay unsigned int i = 0; 434fc179b6SThomas Perrot 44*a37f67edSPatrick Delaunay /* Try GPIO properties "foo-gpios" and "foo-gpio" */ 45*a37f67edSPatrick Delaunay for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { 46*a37f67edSPatrick Delaunay if (gpio_name) 47*a37f67edSPatrick Delaunay snprintf(prop_name, sizeof(prop_name), "%s-%s", 48*a37f67edSPatrick Delaunay gpio_name, gpio_suffixes[i]); 49*a37f67edSPatrick Delaunay else 50*a37f67edSPatrick Delaunay snprintf(prop_name, sizeof(prop_name), "%s", 51*a37f67edSPatrick Delaunay gpio_suffixes[i]); 524fc179b6SThomas Perrot 53*a37f67edSPatrick Delaunay res = dt_driver_device_from_node_idx_prop(prop_name, fdt, 54*a37f67edSPatrick Delaunay nodeoffset, 554fc179b6SThomas Perrot index, DT_DRIVER_GPIO, 56b357d34fSEtienne Carriere &out_gpio); 57*a37f67edSPatrick Delaunay 58*a37f67edSPatrick Delaunay if (res != TEE_ERROR_ITEM_NOT_FOUND) 59*a37f67edSPatrick Delaunay break; 60*a37f67edSPatrick Delaunay } 61*a37f67edSPatrick Delaunay 62b357d34fSEtienne Carriere if (!res) 63b357d34fSEtienne Carriere *gpio = out_gpio; 644fc179b6SThomas Perrot 654fc179b6SThomas Perrot return res; 664fc179b6SThomas Perrot } 67