xref: /optee_os/core/drivers/gpio/gpio.c (revision a37f67ed796a2ac2db3c7e6f09b239d186233e98)
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