summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAnup Patel <anup.patel@wdc.com>2021-07-13 06:23:42 +0300
committerAnup Patel <anup@brainfault.org>2021-07-17 09:12:51 +0300
commit36b8effe4a07bbf476deca6c8769529c69078f08 (patch)
tree7ed406c370b4fc1662bc9175cb8141e1e325f0ff /lib
parente931f387b27a2f575f5b713391e241d8963b48c5 (diff)
downloadopensbi-36b8effe4a07bbf476deca6c8769529c69078f08.tar.xz
lib: utils/gpio: Add generic GPIO configuration library
We add generic GPIO configuration library which is independent of hardware description format (FDT or ACPI). The OpenSBI platform support or GPIO drivers can register GPIO chip instances which can be discovered and used by different GPIO clients. Each GPIO chip instance has a unique ID which can be used by GPIO clients to lookup GPIO chip instance. Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Atish Patra <atish.patra@wdc.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/utils/gpio/gpio.c116
-rw-r--r--lib/utils/gpio/objects.mk10
2 files changed, 126 insertions, 0 deletions
diff --git a/lib/utils/gpio/gpio.c b/lib/utils/gpio/gpio.c
new file mode 100644
index 0000000..fb30c0f
--- /dev/null
+++ b/lib/utils/gpio/gpio.c
@@ -0,0 +1,116 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2021 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#include <sbi/sbi_error.h>
+#include <sbi_utils/gpio/gpio.h>
+
+#define GPIO_CHIP_MAX 16
+
+static struct gpio_chip *gc_array[GPIO_CHIP_MAX];
+
+struct gpio_chip *gpio_chip_find(unsigned int id)
+{
+ unsigned int i;
+ struct gpio_chip *ret = NULL;
+
+ for (i = 0; i < GPIO_CHIP_MAX; i++) {
+ if (gc_array[i] && gc_array[i]->id == id) {
+ ret = gc_array[i];
+ break;
+ }
+ }
+
+ return ret;
+}
+
+int gpio_chip_add(struct gpio_chip *gc)
+{
+ int i, ret = SBI_ENOSPC;
+
+ if (!gc)
+ return SBI_EINVAL;
+ if (gpio_chip_find(gc->id))
+ return SBI_EALREADY;
+
+ for (i = 0; i < GPIO_CHIP_MAX; i++) {
+ if (!gc_array[i]) {
+ gc_array[i] = gc;
+ ret = 0;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+void gpio_chip_remove(struct gpio_chip *gc)
+{
+ int i;
+
+ if (!gc)
+ return;
+
+ for (i = 0; i < GPIO_CHIP_MAX; i++) {
+ if (gc_array[i] == gc) {
+ gc_array[i] = NULL;
+ break;
+ }
+ }
+}
+
+int gpio_get_direction(struct gpio_pin *gp)
+{
+ if (!gp || !gp->chip || (gp->chip->ngpio <= gp->offset))
+ return SBI_EINVAL;
+ if (!gp->chip->get_direction)
+ return SBI_ENOSYS;
+
+ return gp->chip->get_direction(gp);
+}
+
+int gpio_direction_input(struct gpio_pin *gp)
+{
+ if (!gp || !gp->chip || (gp->chip->ngpio <= gp->offset))
+ return SBI_EINVAL;
+ if (!gp->chip->direction_input)
+ return SBI_ENOSYS;
+
+ return gp->chip->direction_input(gp);
+}
+
+int gpio_direction_output(struct gpio_pin *gp, int value)
+{
+ if (!gp || !gp->chip || (gp->chip->ngpio <= gp->offset))
+ return SBI_EINVAL;
+ if (!gp->chip->direction_output)
+ return SBI_ENOSYS;
+
+ return gp->chip->direction_output(gp, value);
+}
+
+int gpio_get(struct gpio_pin *gp)
+{
+ if (!gp || !gp->chip || (gp->chip->ngpio <= gp->offset))
+ return SBI_EINVAL;
+ if (!gp->chip->get)
+ return SBI_ENOSYS;
+
+ return gp->chip->get(gp);
+}
+
+int gpio_set(struct gpio_pin *gp, int value)
+{
+ if (!gp || !gp->chip || (gp->chip->ngpio <= gp->offset))
+ return SBI_EINVAL;
+ if (!gp->chip->set)
+ return SBI_ENOSYS;
+
+ gp->chip->set(gp, value);
+ return 0;
+}
diff --git a/lib/utils/gpio/objects.mk b/lib/utils/gpio/objects.mk
new file mode 100644
index 0000000..e99a895
--- /dev/null
+++ b/lib/utils/gpio/objects.mk
@@ -0,0 +1,10 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2021 Western Digital Corporation or its affiliates.
+#
+# Authors:
+# Anup Patel <anup.patel@wdc.com>
+#
+
+libsbiutils-objs-y += gpio/gpio.o