diff options
Diffstat (limited to 'drivers/gpio/gpiolib-legacy.c')
-rw-r--r-- | drivers/gpio/gpiolib-legacy.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/drivers/gpio/gpiolib-legacy.c b/drivers/gpio/gpiolib-legacy.c new file mode 100644 index 000000000..30e2476a6 --- /dev/null +++ b/drivers/gpio/gpiolib-legacy.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/gpio/consumer.h> +#include <linux/gpio/driver.h> + +#include <linux/gpio.h> + +#include "gpiolib.h" + +void gpio_free(unsigned gpio) +{ + gpiod_free(gpio_to_desc(gpio)); +} +EXPORT_SYMBOL_GPL(gpio_free); + +/** + * gpio_request_one - request a single GPIO with initial configuration + * @gpio: the GPIO number + * @flags: GPIO configuration as specified by GPIOF_* + * @label: a literal description string of this GPIO + */ +int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) +{ + struct gpio_desc *desc; + int err; + + desc = gpio_to_desc(gpio); + + /* Compatibility: assume unavailable "valid" GPIOs will appear later */ + if (!desc && gpio_is_valid(gpio)) + return -EPROBE_DEFER; + + err = gpiod_request(desc, label); + if (err) + return err; + + if (flags & GPIOF_OPEN_DRAIN) + set_bit(FLAG_OPEN_DRAIN, &desc->flags); + + if (flags & GPIOF_OPEN_SOURCE) + set_bit(FLAG_OPEN_SOURCE, &desc->flags); + + if (flags & GPIOF_ACTIVE_LOW) + set_bit(FLAG_ACTIVE_LOW, &desc->flags); + + if (flags & GPIOF_DIR_IN) + err = gpiod_direction_input(desc); + else + err = gpiod_direction_output_raw(desc, + (flags & GPIOF_INIT_HIGH) ? 1 : 0); + + if (err) + goto free_gpio; + + if (flags & GPIOF_EXPORT) { + err = gpiod_export(desc, flags & GPIOF_EXPORT_CHANGEABLE); + if (err) + goto free_gpio; + } + + return 0; + + free_gpio: + gpiod_free(desc); + return err; +} +EXPORT_SYMBOL_GPL(gpio_request_one); + +int gpio_request(unsigned gpio, const char *label) +{ + struct gpio_desc *desc = gpio_to_desc(gpio); + + /* Compatibility: assume unavailable "valid" GPIOs will appear later */ + if (!desc && gpio_is_valid(gpio)) + return -EPROBE_DEFER; + + return gpiod_request(desc, label); +} +EXPORT_SYMBOL_GPL(gpio_request); + +/** + * gpio_request_array - request multiple GPIOs in a single call + * @array: array of the 'struct gpio' + * @num: how many GPIOs in the array + */ +int gpio_request_array(const struct gpio *array, size_t num) +{ + int i, err; + + for (i = 0; i < num; i++, array++) { + err = gpio_request_one(array->gpio, array->flags, array->label); + if (err) + goto err_free; + } + return 0; + +err_free: + while (i--) + gpio_free((--array)->gpio); + return err; +} +EXPORT_SYMBOL_GPL(gpio_request_array); + +/** + * gpio_free_array - release multiple GPIOs in a single call + * @array: array of the 'struct gpio' + * @num: how many GPIOs in the array + */ +void gpio_free_array(const struct gpio *array, size_t num) +{ + while (num--) + gpio_free((array++)->gpio); +} +EXPORT_SYMBOL_GPL(gpio_free_array); |