Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 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); |