xref: /optee_os/core/drivers/gpio/gpio.c (revision a37f67ed796a2ac2db3c7e6f09b239d186233e98)
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_types.h>
11 #include <util.h>
12 
13 /* gpio suffixes used for device tree lookup */
14 static const char * const gpio_suffixes[] = { "gpios", "gpio" };
15 
16 TEE_Result gpio_dt_alloc_pin(struct dt_pargs *pargs, struct gpio **out_gpio)
17 {
18 	struct gpio *gpio = NULL;
19 
20 	if (pargs->args_count != 2)
21 		return TEE_ERROR_BAD_PARAMETERS;
22 
23 	gpio = calloc(1, sizeof(struct gpio));
24 	if (!gpio)
25 		return TEE_ERROR_OUT_OF_MEMORY;
26 
27 	gpio->pin = pargs->args[0];
28 	gpio->dt_flags = pargs->args[1];
29 
30 	*out_gpio = gpio;
31 
32 	return TEE_SUCCESS;
33 }
34 
35 TEE_Result gpio_dt_get_by_index(const void *fdt, int nodeoffset,
36 				unsigned int index, const char *gpio_name,
37 				struct gpio **gpio)
38 {
39 	TEE_Result res = TEE_ERROR_GENERIC;
40 	char prop_name[32]; /* 32 is max size of property name in DT */
41 	void *out_gpio = NULL;
42 	unsigned int i = 0;
43 
44 	/* Try GPIO properties "foo-gpios" and "foo-gpio" */
45 	for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
46 		if (gpio_name)
47 			snprintf(prop_name, sizeof(prop_name), "%s-%s",
48 				 gpio_name, gpio_suffixes[i]);
49 		else
50 			snprintf(prop_name, sizeof(prop_name), "%s",
51 				 gpio_suffixes[i]);
52 
53 		res = dt_driver_device_from_node_idx_prop(prop_name, fdt,
54 							  nodeoffset,
55 							  index, DT_DRIVER_GPIO,
56 							  &out_gpio);
57 
58 		if (res != TEE_ERROR_ITEM_NOT_FOUND)
59 			break;
60 	}
61 
62 	if (!res)
63 		*gpio = out_gpio;
64 
65 	return res;
66 }
67