blob: c5f58fbf11b53f5642196973f394643e0cd87d5a [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0
#include <linux/export.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
/**
* gpiod_configure_flags - helper function to configure a given GPIO
* @desc: gpio whose value will be assigned
* @con_id: function within the GPIO consumer
* @lflags: bitmask of gpio_lookup_flags GPIO_* values - returned from
* of_find_gpio() or of_get_gpio_hog()
* @dflags: gpiod_flags - optional GPIO initialization flags
*
* Return 0 on success, -ENOENT if no GPIO has been assigned to the
* requested function and/or index, or another IS_ERR() code if an error
* occurred while trying to acquire the GPIO.
*/
static int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
unsigned long lflags, enum gpiod_flags dflags)
{
int ret;
#ifdef GPIO_TRANSITORY
ret = gpiod_set_transitory(desc, (lflags & GPIO_TRANSITORY));
if (ret < 0)
return ret;
#endif
/* No particular flag request, return here... */
if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET))
return 0;
/* Process flags */
if (dflags & GPIOD_FLAGS_BIT_DIR_OUT)
ret = gpiod_direction_output(desc,
!!(dflags & GPIOD_FLAGS_BIT_DIR_VAL));
else
ret = gpiod_direction_input(desc);
return ret;
}
#undef gpiochip_request_own_desc
/* In kernels older than 5.4, these function declarations are inside a
* CONFIG_GPIOLIB ifdef, so we need to declare them here.
*/
#ifndef CONFIG_GPIOLIB
extern struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *chip,
u16 hwnum,
const char *label);
void gpiochip_free_own_desc(struct gpio_desc *desc);
#endif /* CONFIG_GPIOLIB */
struct gpio_desc *backport_gpiochip_request_own_desc(struct gpio_chip *gc,
unsigned int hwnum,
const char *label,
enum gpio_lookup_flags lflags,
enum gpiod_flags dflags)
{
struct gpio_desc *desc;
int ret;
#if LINUX_VERSION_IS_GEQ(5,0,0)
desc = gpiochip_request_own_desc(gc, hwnum, label, dflags);
#else
desc = gpiochip_request_own_desc(gc, hwnum, label);
#endif
if (IS_ERR(desc))
return desc;
ret = gpiod_configure_flags(desc, label, lflags, dflags);
if (ret) {
gpiochip_free_own_desc(desc);
return ERR_PTR(ret);
}
return desc;
}
EXPORT_SYMBOL_GPL(backport_gpiochip_request_own_desc);