1122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot#include <linux/gpio/consumer.h>
2122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot#include <linux/gpio/driver.h>
3122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
4122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot#include <linux/gpio.h>
5122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
6122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot#include "gpiolib.h"
7122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
8122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbotvoid gpio_free(unsigned gpio)
9122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot{
10122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	gpiod_free(gpio_to_desc(gpio));
11122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot}
12122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre CourbotEXPORT_SYMBOL_GPL(gpio_free);
13122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
14122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot/**
15122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot * gpio_request_one - request a single GPIO with initial configuration
16122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot * @gpio:	the GPIO number
17122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot * @flags:	GPIO configuration as specified by GPIOF_*
18122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot * @label:	a literal description string of this GPIO
19122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot */
20122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbotint gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
21122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot{
22122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	struct gpio_desc *desc;
23122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	int err;
24122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
25122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	desc = gpio_to_desc(gpio);
26122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
27122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	err = gpiod_request(desc, label);
28122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	if (err)
29122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot		return err;
30122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
31122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	if (flags & GPIOF_OPEN_DRAIN)
32122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot		set_bit(FLAG_OPEN_DRAIN, &desc->flags);
33122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
34122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	if (flags & GPIOF_OPEN_SOURCE)
35122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot		set_bit(FLAG_OPEN_SOURCE, &desc->flags);
36122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
372be001739242fac1083f3b21898158492844699dGuenter Roeck	if (flags & GPIOF_ACTIVE_LOW)
382be001739242fac1083f3b21898158492844699dGuenter Roeck		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
392be001739242fac1083f3b21898158492844699dGuenter Roeck
40122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	if (flags & GPIOF_DIR_IN)
41122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot		err = gpiod_direction_input(desc);
42122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	else
43122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot		err = gpiod_direction_output_raw(desc,
44122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot				(flags & GPIOF_INIT_HIGH) ? 1 : 0);
45122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
46122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	if (err)
47122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot		goto free_gpio;
48122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
49122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	if (flags & GPIOF_EXPORT) {
50122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot		err = gpiod_export(desc, flags & GPIOF_EXPORT_CHANGEABLE);
51122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot		if (err)
52122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot			goto free_gpio;
53122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	}
54122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
55122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	return 0;
56122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
57122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot free_gpio:
58122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	gpiod_free(desc);
59122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	return err;
60122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot}
61122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre CourbotEXPORT_SYMBOL_GPL(gpio_request_one);
62122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
63122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbotint gpio_request(unsigned gpio, const char *label)
64122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot{
65122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	return gpiod_request(gpio_to_desc(gpio), label);
66122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot}
67122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre CourbotEXPORT_SYMBOL_GPL(gpio_request);
68122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
69122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot/**
70122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot * gpio_request_array - request multiple GPIOs in a single call
71122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot * @array:	array of the 'struct gpio'
72122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot * @num:	how many GPIOs in the array
73122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot */
74122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbotint gpio_request_array(const struct gpio *array, size_t num)
75122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot{
76122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	int i, err;
77122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
78122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	for (i = 0; i < num; i++, array++) {
79122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot		err = gpio_request_one(array->gpio, array->flags, array->label);
80122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot		if (err)
81122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot			goto err_free;
82122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	}
83122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	return 0;
84122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
85122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courboterr_free:
86122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	while (i--)
87122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot		gpio_free((--array)->gpio);
88122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	return err;
89122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot}
90122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre CourbotEXPORT_SYMBOL_GPL(gpio_request_array);
91122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot
92122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot/**
93122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot * gpio_free_array - release multiple GPIOs in a single call
94122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot * @array:	array of the 'struct gpio'
95122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot * @num:	how many GPIOs in the array
96122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot */
97122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbotvoid gpio_free_array(const struct gpio *array, size_t num)
98122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot{
99122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot	while (num--)
100122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot		gpio_free((array++)->gpio);
101122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre Courbot}
102122c94dec7f6909ff6999f6207b124e6db5d2ba8Alexandre CourbotEXPORT_SYMBOL_GPL(gpio_free_array);
103