diff options
| author | Anup Patel <[email protected]> | 2021-07-13 11:23:42 +0800 |
|---|---|---|
| committer | Anup Patel <[email protected]> | 2021-07-17 11:42:51 +0530 |
| commit | 36b8effe4a07bbf476deca6c8769529c69078f08 (patch) | |
| tree | 7ed406c370b4fc1662bc9175cb8141e1e325f0ff /lib | |
| parent | e931f387b27a2f575f5b713391e241d8963b48c5 (diff) | |
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 <[email protected]>
Reviewed-by: Atish Patra <[email protected]>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/utils/gpio/gpio.c | 116 | ||||
| -rw-r--r-- | lib/utils/gpio/objects.mk | 10 |
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 00000000..fb30c0f7 --- /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 <[email protected]> + */ + +#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 00000000..e99a895c --- /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 <[email protected]> +# + +libsbiutils-objs-y += gpio/gpio.o |
