summaryrefslogtreecommitdiffstats
path: root/libopenbmc_intf/gpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'libopenbmc_intf/gpio.c')
-rw-r--r--libopenbmc_intf/gpio.c92
1 files 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 <argp.h>
#include <sys/stat.h>
#include <sys/mman.h>
+#include <dirent.h>
#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<X> 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;
}
/**
OpenPOWER on IntegriCloud