162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include <linux/gpio/consumer.h>
362306a36Sopenharmony_ci#include <linux/gpio/driver.h>
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/gpio.h>
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include "gpiolib.h"
862306a36Sopenharmony_ci
962306a36Sopenharmony_civoid gpio_free(unsigned gpio)
1062306a36Sopenharmony_ci{
1162306a36Sopenharmony_ci	gpiod_free(gpio_to_desc(gpio));
1262306a36Sopenharmony_ci}
1362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(gpio_free);
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/**
1662306a36Sopenharmony_ci * gpio_request_one - request a single GPIO with initial configuration
1762306a36Sopenharmony_ci * @gpio:	the GPIO number
1862306a36Sopenharmony_ci * @flags:	GPIO configuration as specified by GPIOF_*
1962306a36Sopenharmony_ci * @label:	a literal description string of this GPIO
2062306a36Sopenharmony_ci */
2162306a36Sopenharmony_ciint gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
2262306a36Sopenharmony_ci{
2362306a36Sopenharmony_ci	struct gpio_desc *desc;
2462306a36Sopenharmony_ci	int err;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	desc = gpio_to_desc(gpio);
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci	/* Compatibility: assume unavailable "valid" GPIOs will appear later */
2962306a36Sopenharmony_ci	if (!desc && gpio_is_valid(gpio))
3062306a36Sopenharmony_ci		return -EPROBE_DEFER;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	err = gpiod_request(desc, label);
3362306a36Sopenharmony_ci	if (err)
3462306a36Sopenharmony_ci		return err;
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	if (flags & GPIOF_ACTIVE_LOW)
3762306a36Sopenharmony_ci		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	if (flags & GPIOF_DIR_IN)
4062306a36Sopenharmony_ci		err = gpiod_direction_input(desc);
4162306a36Sopenharmony_ci	else
4262306a36Sopenharmony_ci		err = gpiod_direction_output_raw(desc,
4362306a36Sopenharmony_ci				(flags & GPIOF_INIT_HIGH) ? 1 : 0);
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	if (err)
4662306a36Sopenharmony_ci		goto free_gpio;
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	return 0;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci free_gpio:
5162306a36Sopenharmony_ci	gpiod_free(desc);
5262306a36Sopenharmony_ci	return err;
5362306a36Sopenharmony_ci}
5462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(gpio_request_one);
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ciint gpio_request(unsigned gpio, const char *label)
5762306a36Sopenharmony_ci{
5862306a36Sopenharmony_ci	struct gpio_desc *desc = gpio_to_desc(gpio);
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	/* Compatibility: assume unavailable "valid" GPIOs will appear later */
6162306a36Sopenharmony_ci	if (!desc && gpio_is_valid(gpio))
6262306a36Sopenharmony_ci		return -EPROBE_DEFER;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	return gpiod_request(desc, label);
6562306a36Sopenharmony_ci}
6662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(gpio_request);
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci/**
6962306a36Sopenharmony_ci * gpio_request_array - request multiple GPIOs in a single call
7062306a36Sopenharmony_ci * @array:	array of the 'struct gpio'
7162306a36Sopenharmony_ci * @num:	how many GPIOs in the array
7262306a36Sopenharmony_ci */
7362306a36Sopenharmony_ciint gpio_request_array(const struct gpio *array, size_t num)
7462306a36Sopenharmony_ci{
7562306a36Sopenharmony_ci	int i, err;
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	for (i = 0; i < num; i++, array++) {
7862306a36Sopenharmony_ci		err = gpio_request_one(array->gpio, array->flags, array->label);
7962306a36Sopenharmony_ci		if (err)
8062306a36Sopenharmony_ci			goto err_free;
8162306a36Sopenharmony_ci	}
8262306a36Sopenharmony_ci	return 0;
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_cierr_free:
8562306a36Sopenharmony_ci	while (i--)
8662306a36Sopenharmony_ci		gpio_free((--array)->gpio);
8762306a36Sopenharmony_ci	return err;
8862306a36Sopenharmony_ci}
8962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(gpio_request_array);
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci/**
9262306a36Sopenharmony_ci * gpio_free_array - release multiple GPIOs in a single call
9362306a36Sopenharmony_ci * @array:	array of the 'struct gpio'
9462306a36Sopenharmony_ci * @num:	how many GPIOs in the array
9562306a36Sopenharmony_ci */
9662306a36Sopenharmony_civoid gpio_free_array(const struct gpio *array, size_t num)
9762306a36Sopenharmony_ci{
9862306a36Sopenharmony_ci	while (num--)
9962306a36Sopenharmony_ci		gpio_free((array++)->gpio);
10062306a36Sopenharmony_ci}
10162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(gpio_free_array);
102