xref: /optee_os/core/drivers/gpio/gpio.c (revision b357d34fe91f4e7f6e0eacea17a7fbe5f6c01e7e)
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_defines_extensions.h>
114fc179b6SThomas Perrot #include <tee_api_types.h>
124fc179b6SThomas Perrot #include <util.h>
134fc179b6SThomas Perrot 
14*b357d34fSEtienne Carriere TEE_Result gpio_dt_alloc_pin(struct dt_pargs *pargs, struct gpio **out_gpio)
154fc179b6SThomas Perrot {
164fc179b6SThomas Perrot 	struct gpio *gpio = NULL;
174fc179b6SThomas Perrot 
18*b357d34fSEtienne Carriere 	if (pargs->args_count != 2)
19*b357d34fSEtienne Carriere 		return TEE_ERROR_BAD_PARAMETERS;
204fc179b6SThomas Perrot 
214fc179b6SThomas Perrot 	gpio = calloc(1, sizeof(struct gpio));
22*b357d34fSEtienne Carriere 	if (!gpio)
23*b357d34fSEtienne Carriere 		return TEE_ERROR_OUT_OF_MEMORY;
244fc179b6SThomas Perrot 
258fd620f7SEtienne Carriere 	gpio->pin = pargs->args[0];
268fd620f7SEtienne Carriere 	gpio->dt_flags = pargs->args[1];
274fc179b6SThomas Perrot 
28*b357d34fSEtienne Carriere 	*out_gpio = gpio;
29*b357d34fSEtienne Carriere 
30*b357d34fSEtienne Carriere 	return TEE_SUCCESS;
314fc179b6SThomas Perrot }
324fc179b6SThomas Perrot 
334fc179b6SThomas Perrot static char *gpio_get_dt_prop_name(const char *gpio_name)
344fc179b6SThomas Perrot {
354fc179b6SThomas Perrot 	char *prop_name = NULL;
364fc179b6SThomas Perrot 	int max_len = strlen(gpio_name) + strlen("-gpios") + 1;
374fc179b6SThomas Perrot 
384fc179b6SThomas Perrot 	prop_name = calloc(1, max_len);
394fc179b6SThomas Perrot 	if (!prop_name)
404fc179b6SThomas Perrot 		return NULL;
414fc179b6SThomas Perrot 
424fc179b6SThomas Perrot 	snprintf(prop_name, max_len, "%s-gpios", gpio_name);
434fc179b6SThomas Perrot 
444fc179b6SThomas Perrot 	return prop_name;
454fc179b6SThomas Perrot }
464fc179b6SThomas Perrot 
474fc179b6SThomas Perrot TEE_Result gpio_dt_get_by_index(const void *fdt, int nodeoffset,
484fc179b6SThomas Perrot 				unsigned int index, const char *gpio_name,
494fc179b6SThomas Perrot 				struct gpio **gpio)
504fc179b6SThomas Perrot {
514fc179b6SThomas Perrot 	TEE_Result res = TEE_ERROR_GENERIC;
524fc179b6SThomas Perrot 	char *prop_name = NULL;
53*b357d34fSEtienne Carriere 	void *out_gpio = NULL;
544fc179b6SThomas Perrot 
554fc179b6SThomas Perrot 	prop_name = gpio_get_dt_prop_name(gpio_name);
564fc179b6SThomas Perrot 	if (!prop_name)
574fc179b6SThomas Perrot 		return TEE_ERROR_OUT_OF_MEMORY;
584fc179b6SThomas Perrot 
59*b357d34fSEtienne Carriere 	res = dt_driver_device_from_node_idx_prop(prop_name, fdt, nodeoffset,
604fc179b6SThomas Perrot 						  index, DT_DRIVER_GPIO,
61*b357d34fSEtienne Carriere 						  &out_gpio);
624fc179b6SThomas Perrot 	free(prop_name);
63*b357d34fSEtienne Carriere 	if (!res)
64*b357d34fSEtienne Carriere 		*gpio = out_gpio;
654fc179b6SThomas Perrot 
664fc179b6SThomas Perrot 	return res;
674fc179b6SThomas Perrot }
68