xref: /optee_os/core/drivers/gpio/gpio.c (revision 8fd620f75b68cd47c13807b45b78ea9c931de9b6)
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*8fd620f7SEtienne Carriere struct gpio *gpio_dt_alloc_pin(struct dt_pargs *pargs, TEE_Result *res)
154fc179b6SThomas Perrot {
164fc179b6SThomas Perrot 	struct gpio *gpio = NULL;
174fc179b6SThomas Perrot 
18*8fd620f7SEtienne Carriere 	if (pargs->args_count != 2) {
194fc179b6SThomas Perrot 		*res = TEE_ERROR_BAD_PARAMETERS;
204fc179b6SThomas Perrot 		return NULL;
214fc179b6SThomas Perrot 	}
224fc179b6SThomas Perrot 
234fc179b6SThomas Perrot 	gpio = calloc(1, sizeof(struct gpio));
244fc179b6SThomas Perrot 	if (!gpio) {
254fc179b6SThomas Perrot 		*res = TEE_ERROR_OUT_OF_MEMORY;
264fc179b6SThomas Perrot 		return NULL;
274fc179b6SThomas Perrot 	}
284fc179b6SThomas Perrot 
29*8fd620f7SEtienne Carriere 	gpio->pin = pargs->args[0];
30*8fd620f7SEtienne Carriere 	gpio->dt_flags = pargs->args[1];
314fc179b6SThomas Perrot 
324fc179b6SThomas Perrot 	*res = TEE_SUCCESS;
334fc179b6SThomas Perrot 	return gpio;
344fc179b6SThomas Perrot }
354fc179b6SThomas Perrot 
364fc179b6SThomas Perrot static char *gpio_get_dt_prop_name(const char *gpio_name)
374fc179b6SThomas Perrot {
384fc179b6SThomas Perrot 	char *prop_name = NULL;
394fc179b6SThomas Perrot 	int max_len = strlen(gpio_name) + strlen("-gpios") + 1;
404fc179b6SThomas Perrot 
414fc179b6SThomas Perrot 	prop_name = calloc(1, max_len);
424fc179b6SThomas Perrot 	if (!prop_name)
434fc179b6SThomas Perrot 		return NULL;
444fc179b6SThomas Perrot 
454fc179b6SThomas Perrot 	snprintf(prop_name, max_len, "%s-gpios", gpio_name);
464fc179b6SThomas Perrot 
474fc179b6SThomas Perrot 	return prop_name;
484fc179b6SThomas Perrot }
494fc179b6SThomas Perrot 
504fc179b6SThomas Perrot TEE_Result gpio_dt_get_by_index(const void *fdt, int nodeoffset,
514fc179b6SThomas Perrot 				unsigned int index, const char *gpio_name,
524fc179b6SThomas Perrot 				struct gpio **gpio)
534fc179b6SThomas Perrot {
544fc179b6SThomas Perrot 	TEE_Result res = TEE_ERROR_GENERIC;
554fc179b6SThomas Perrot 	char *prop_name = NULL;
564fc179b6SThomas Perrot 
574fc179b6SThomas Perrot 	prop_name = gpio_get_dt_prop_name(gpio_name);
584fc179b6SThomas Perrot 	if (!prop_name)
594fc179b6SThomas Perrot 		return TEE_ERROR_OUT_OF_MEMORY;
604fc179b6SThomas Perrot 
614fc179b6SThomas Perrot 	*gpio = dt_driver_device_from_node_idx_prop(prop_name, fdt, nodeoffset,
624fc179b6SThomas Perrot 						    index, DT_DRIVER_GPIO,
634fc179b6SThomas Perrot 						    &res);
644fc179b6SThomas Perrot 	free(prop_name);
654fc179b6SThomas Perrot 
664fc179b6SThomas Perrot 	return res;
674fc179b6SThomas Perrot }
68