1*dae5f0afSLinus Walleij // SPDX-License-Identifier: GPL-2.0
2122c94deSAlexandre Courbot #include <linux/gpio/consumer.h>
3122c94deSAlexandre Courbot #include <linux/gpio/driver.h>
4122c94deSAlexandre Courbot
5122c94deSAlexandre Courbot #include <linux/gpio.h>
6122c94deSAlexandre Courbot
7122c94deSAlexandre Courbot #include "gpiolib.h"
8122c94deSAlexandre Courbot
gpio_free(unsigned gpio)9122c94deSAlexandre Courbot void gpio_free(unsigned gpio)
10122c94deSAlexandre Courbot {
11122c94deSAlexandre Courbot gpiod_free(gpio_to_desc(gpio));
12122c94deSAlexandre Courbot }
13122c94deSAlexandre Courbot EXPORT_SYMBOL_GPL(gpio_free);
14122c94deSAlexandre Courbot
15122c94deSAlexandre Courbot /**
16122c94deSAlexandre Courbot * gpio_request_one - request a single GPIO with initial configuration
17122c94deSAlexandre Courbot * @gpio: the GPIO number
18122c94deSAlexandre Courbot * @flags: GPIO configuration as specified by GPIOF_*
19122c94deSAlexandre Courbot * @label: a literal description string of this GPIO
20122c94deSAlexandre Courbot */
gpio_request_one(unsigned gpio,unsigned long flags,const char * label)21122c94deSAlexandre Courbot int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
22122c94deSAlexandre Courbot {
23122c94deSAlexandre Courbot struct gpio_desc *desc;
24122c94deSAlexandre Courbot int err;
25122c94deSAlexandre Courbot
26122c94deSAlexandre Courbot desc = gpio_to_desc(gpio);
27122c94deSAlexandre Courbot
280e9a5edfSAlexandre Courbot /* Compatibility: assume unavailable "valid" GPIOs will appear later */
290e9a5edfSAlexandre Courbot if (!desc && gpio_is_valid(gpio))
300e9a5edfSAlexandre Courbot return -EPROBE_DEFER;
310e9a5edfSAlexandre Courbot
3285b03b30SJohan Hovold err = gpiod_request(desc, label);
3385b03b30SJohan Hovold if (err)
3485b03b30SJohan Hovold return err;
3585b03b30SJohan Hovold
362be00173SGuenter Roeck if (flags & GPIOF_ACTIVE_LOW)
372be00173SGuenter Roeck set_bit(FLAG_ACTIVE_LOW, &desc->flags);
382be00173SGuenter Roeck
39122c94deSAlexandre Courbot if (flags & GPIOF_DIR_IN)
40122c94deSAlexandre Courbot err = gpiod_direction_input(desc);
41122c94deSAlexandre Courbot else
42122c94deSAlexandre Courbot err = gpiod_direction_output_raw(desc,
43122c94deSAlexandre Courbot (flags & GPIOF_INIT_HIGH) ? 1 : 0);
44122c94deSAlexandre Courbot
45122c94deSAlexandre Courbot if (err)
46122c94deSAlexandre Courbot goto free_gpio;
47122c94deSAlexandre Courbot
48122c94deSAlexandre Courbot return 0;
49122c94deSAlexandre Courbot
50122c94deSAlexandre Courbot free_gpio:
51122c94deSAlexandre Courbot gpiod_free(desc);
52122c94deSAlexandre Courbot return err;
53122c94deSAlexandre Courbot }
54122c94deSAlexandre Courbot EXPORT_SYMBOL_GPL(gpio_request_one);
55122c94deSAlexandre Courbot
gpio_request(unsigned gpio,const char * label)56122c94deSAlexandre Courbot int gpio_request(unsigned gpio, const char *label)
57122c94deSAlexandre Courbot {
580e9a5edfSAlexandre Courbot struct gpio_desc *desc = gpio_to_desc(gpio);
590e9a5edfSAlexandre Courbot
600e9a5edfSAlexandre Courbot /* Compatibility: assume unavailable "valid" GPIOs will appear later */
610e9a5edfSAlexandre Courbot if (!desc && gpio_is_valid(gpio))
620e9a5edfSAlexandre Courbot return -EPROBE_DEFER;
630e9a5edfSAlexandre Courbot
640e9a5edfSAlexandre Courbot return gpiod_request(desc, label);
65122c94deSAlexandre Courbot }
66122c94deSAlexandre Courbot EXPORT_SYMBOL_GPL(gpio_request);
67122c94deSAlexandre Courbot
68122c94deSAlexandre Courbot /**
69122c94deSAlexandre Courbot * gpio_request_array - request multiple GPIOs in a single call
70122c94deSAlexandre Courbot * @array: array of the 'struct gpio'
71122c94deSAlexandre Courbot * @num: how many GPIOs in the array
72122c94deSAlexandre Courbot */
gpio_request_array(const struct gpio * array,size_t num)73122c94deSAlexandre Courbot int gpio_request_array(const struct gpio *array, size_t num)
74122c94deSAlexandre Courbot {
75122c94deSAlexandre Courbot int i, err;
76122c94deSAlexandre Courbot
77122c94deSAlexandre Courbot for (i = 0; i < num; i++, array++) {
78122c94deSAlexandre Courbot err = gpio_request_one(array->gpio, array->flags, array->label);
79122c94deSAlexandre Courbot if (err)
80122c94deSAlexandre Courbot goto err_free;
81122c94deSAlexandre Courbot }
82122c94deSAlexandre Courbot return 0;
83122c94deSAlexandre Courbot
84122c94deSAlexandre Courbot err_free:
85122c94deSAlexandre Courbot while (i--)
86122c94deSAlexandre Courbot gpio_free((--array)->gpio);
87122c94deSAlexandre Courbot return err;
88122c94deSAlexandre Courbot }
89122c94deSAlexandre Courbot EXPORT_SYMBOL_GPL(gpio_request_array);
90122c94deSAlexandre Courbot
91122c94deSAlexandre Courbot /**
92122c94deSAlexandre Courbot * gpio_free_array - release multiple GPIOs in a single call
93122c94deSAlexandre Courbot * @array: array of the 'struct gpio'
94122c94deSAlexandre Courbot * @num: how many GPIOs in the array
95122c94deSAlexandre Courbot */
gpio_free_array(const struct gpio * array,size_t num)96122c94deSAlexandre Courbot void gpio_free_array(const struct gpio *array, size_t num)
97122c94deSAlexandre Courbot {
98122c94deSAlexandre Courbot while (num--)
99122c94deSAlexandre Courbot gpio_free((array++)->gpio);
100122c94deSAlexandre Courbot }
101122c94deSAlexandre Courbot EXPORT_SYMBOL_GPL(gpio_free_array);
102