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