From e2cd39d8585dce09c8acddf07fd5ed2b0a619ebc Mon Sep 17 00:00:00 2001 From: Matt Spinler Date: Tue, 7 Aug 2018 14:32:58 -0500 Subject: Fill in the function that finds the GPIO base Finds the GPIO base value to use in the GPIO number calculation. This is most likely specific to ASPEED BMCs, though as with the calling code additional support can be added in the future if required. Change-Id: Ie0d2b87286ab4bf6b05b61245bd821ab2a9d602a Signed-off-by: Matt Spinler --- libopenbmc_intf/gpio.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/libopenbmc_intf/gpio.c b/libopenbmc_intf/gpio.c index 2fe1421..a33348b 100644 --- a/libopenbmc_intf/gpio.c +++ b/libopenbmc_intf/gpio.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "openbmc_intf.h" #include "gpio.h" #include "gpio_json.h" @@ -106,10 +107,97 @@ int gpio_clock_cycle(GPIO* gpio, int num_clks) { return r; } +/** + * Determine the GPIO base number for the system. It is found in + * the 'base' file in the /sys/class/gpio/gpiochipX/ directory where the + * /sys/class/gpio/gpiochipX/label file has a '1e780000.gpio' in it. + * + * Note: This method is ASPEED specific. Could add support for + * additional SOCs in the future. + * + * @return int - the GPIO base number, or < 0 if not found + */ int get_gpio_base() { - /* TODO */ - return 0; + int gpio_base = -1; + + DIR* dir = opendir(GPIO_BASE_PATH); + if (dir == NULL) + { + fprintf(stderr, "Unable to open directory %s\n", + GPIO_BASE_PATH); + return -1; + } + + struct dirent* entry; + while ((entry = readdir(dir)) != NULL) + { + /* Look in the gpiochip directories for a file called 'label' */ + /* that contains '1e780000.gpio', then in that directory read */ + /* the GPIO base out of the 'base' file. */ + + if (strncmp(entry->d_name, "gpiochip", 8) != 0) + { + continue; + } + + gboolean is_bmc = FALSE; + char* label_name; + asprintf(&label_name, "%s/%s/label", + GPIO_BASE_PATH, entry->d_name); + + FILE* fd = fopen(label_name, "r"); + free(label_name); + + if (!fd) + { + continue; + } + + char label[14]; + if (fgets(label, 14, fd) != NULL) + { + if (strcmp(label, "1e780000.gpio") == 0) + { + is_bmc = TRUE; + } + } + fclose(fd); + + if (!is_bmc) + { + continue; + } + + char* base_name; + asprintf(&base_name, "%s/%s/base", + GPIO_BASE_PATH, entry->d_name); + + fd = fopen(base_name, "r"); + free(base_name); + + if (!fd) + { + continue; + } + + if (fscanf(fd, "%d", &gpio_base) != 1) + { + gpio_base = -1; + } + fclose(fd); + + /* We found the right file. No need to continue. */ + break; + } + closedir(dir); + + if (gpio_base == -1) + { + fprintf(stderr, "Could not find GPIO base\n"); + } + + return gpio_base; } /** -- cgit v1.2.1