xref: /optee_os/core/drivers/gpio/gpio.c (revision 5f7f88c6b9d618d1e068166bbf2b07757350791d)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2022, Microchip
4  */
5 
6 #include <drivers/gpio.h>
7 #include <libfdt.h>
8 #include <stdio.h>
9 #include <tee_api_defines.h>
10 #include <tee_api_defines_extensions.h>
11 #include <tee_api_types.h>
12 #include <util.h>
13 
14 TEE_Result gpio_dt_alloc_pin(struct dt_pargs *pargs, struct gpio **out_gpio)
15 {
16 	struct gpio *gpio = NULL;
17 
18 	if (pargs->args_count != 2)
19 		return TEE_ERROR_BAD_PARAMETERS;
20 
21 	gpio = calloc(1, sizeof(struct gpio));
22 	if (!gpio)
23 		return TEE_ERROR_OUT_OF_MEMORY;
24 
25 	gpio->pin = pargs->args[0];
26 	gpio->dt_flags = pargs->args[1];
27 
28 	*out_gpio = gpio;
29 
30 	return TEE_SUCCESS;
31 }
32 
33 static char *gpio_get_dt_prop_name(const char *gpio_name)
34 {
35 	int ret = 0;
36 	char *prop_name = NULL;
37 	size_t max_len = strlen(gpio_name) + strlen("-gpios") + 1;
38 
39 	prop_name = calloc(1, max_len);
40 	if (!prop_name)
41 		return NULL;
42 
43 	ret = snprintf(prop_name, max_len, "%s-gpios", gpio_name);
44 	if (ret < 0 || (size_t)ret >= max_len) {
45 		free(prop_name);
46 		return NULL;
47 	}
48 
49 	return prop_name;
50 }
51 
52 TEE_Result gpio_dt_get_by_index(const void *fdt, int nodeoffset,
53 				unsigned int index, const char *gpio_name,
54 				struct gpio **gpio)
55 {
56 	TEE_Result res = TEE_ERROR_GENERIC;
57 	char *prop_name = NULL;
58 	void *out_gpio = NULL;
59 
60 	prop_name = gpio_get_dt_prop_name(gpio_name);
61 	if (!prop_name)
62 		return TEE_ERROR_OUT_OF_MEMORY;
63 
64 	res = dt_driver_device_from_node_idx_prop(prop_name, fdt, nodeoffset,
65 						  index, DT_DRIVER_GPIO,
66 						  &out_gpio);
67 	free(prop_name);
68 	if (!res)
69 		*gpio = out_gpio;
70 
71 	return res;
72 }
73