Source
x
* gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2013 Google, Inc
*/
DECLARE_GLOBAL_DATA_PTR;
/**
* gpio_to_device() - Convert global GPIO number to device, number
*
* Convert the GPIO number to an entry in the list of GPIOs
* or GPIO blocks registered with the GPIO controller. Returns
* entry on success, NULL on error.
*
* @gpio: The numeric representation of the GPIO
* @desc: Returns description (desc->flags will always be 0)
* @return 0 if found, -ENOENT if not found
*/
static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
{
struct gpio_dev_priv *uc_priv;
struct udevice *dev;
int ret;
for (ret = uclass_first_device(UCLASS_GPIO, &dev);
dev;
ret = uclass_next_device(&dev)) {
uc_priv = dev_get_uclass_priv(dev);
if (gpio >= uc_priv->gpio_base &&
gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
desc->dev = dev;
desc->offset = gpio - uc_priv->gpio_base;
desc->flags = 0;
return 0;
}
}
/* No such GPIO */
return ret ? ret : -ENOENT;
}
int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
{
struct gpio_dev_priv *uc_priv = NULL;
struct udevice *dev;
ulong offset;
int numeric;
int ret;
numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
for (ret = uclass_first_device(UCLASS_GPIO, &dev);
dev;
ret = uclass_next_device(&dev)) {
int len;
uc_priv = dev_get_uclass_priv(dev);
if (numeric != -1) {
offset = numeric - uc_priv->gpio_base;
/* Allow GPIOs to be numbered from 0 */
if (offset < uc_priv->gpio_count)
break;
}
len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
if (!strncasecmp(name, uc_priv->bank_name, len)) {
if (!strict_strtoul(name + len, 10, &offset))
break;
}
}
if (!dev)
return ret ? ret : -EINVAL;
desc->dev = dev;
desc->offset = offset;
return 0;
}