xref: /openbmc/linux/drivers/gpio/gpiolib-legacy.c (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
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