dm: Move the function for getting GPIO status into the uclass
This function can be more easily tested if it is in the uclass. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
6449a506d6
commit
0757535a7e
@ -25,13 +25,6 @@ enum gpio_cmd {
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DM_GPIO) && !defined(gpio_status)
|
||||
static const char * const gpio_function[GPIOF_COUNT] = {
|
||||
"input",
|
||||
"output",
|
||||
"unused",
|
||||
"unknown",
|
||||
"func",
|
||||
};
|
||||
|
||||
/* A few flags used by show_gpio() */
|
||||
enum {
|
||||
@ -40,22 +33,16 @@ enum {
|
||||
FLAG_SHOW_NEWLINE = 1 << 2,
|
||||
};
|
||||
|
||||
static void show_gpio(struct udevice *dev, const char *bank_name, int offset,
|
||||
int *flagsp)
|
||||
static void gpio_get_description(struct udevice *dev, const char *bank_name,
|
||||
int offset, int *flagsp)
|
||||
{
|
||||
struct dm_gpio_ops *ops = gpio_get_ops(dev);
|
||||
int func = GPIOF_UNKNOWN;
|
||||
char buf[80];
|
||||
int ret;
|
||||
|
||||
BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
|
||||
|
||||
if (ops->get_function) {
|
||||
ret = ops->get_function(dev, offset);
|
||||
if (ret >= 0 && ret < ARRAY_SIZE(gpio_function))
|
||||
func = ret;
|
||||
}
|
||||
if (!(*flagsp & FLAG_SHOW_ALL) && func == GPIOF_UNUSED)
|
||||
ret = gpio_get_function(dev, offset, NULL);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
if (!(*flagsp & FLAG_SHOW_ALL) && ret == GPIOF_UNUSED)
|
||||
return;
|
||||
if ((*flagsp & FLAG_SHOW_BANK) && bank_name) {
|
||||
if (*flagsp & FLAG_SHOW_NEWLINE) {
|
||||
@ -65,20 +52,15 @@ static void show_gpio(struct udevice *dev, const char *bank_name, int offset,
|
||||
printf("Bank %s:\n", bank_name);
|
||||
*flagsp &= ~FLAG_SHOW_BANK;
|
||||
}
|
||||
*buf = '\0';
|
||||
if (ops->get_state) {
|
||||
ret = ops->get_state(dev, offset, buf, sizeof(buf));
|
||||
if (ret) {
|
||||
puts("<unknown>");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
sprintf(buf, "%s%u: %8s %d", bank_name, offset,
|
||||
gpio_function[func], ops->get_value(dev, offset));
|
||||
}
|
||||
|
||||
puts(buf);
|
||||
puts("\n");
|
||||
ret = gpio_get_status(dev, offset, buf, sizeof(buf));
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
printf("%s\n", buf);
|
||||
return;
|
||||
err:
|
||||
printf("Error %d\n", ret);
|
||||
}
|
||||
|
||||
static int do_gpio_status(bool all, const char *gpio_name)
|
||||
@ -101,8 +83,10 @@ static int do_gpio_status(bool all, const char *gpio_name)
|
||||
if (all)
|
||||
flags |= FLAG_SHOW_ALL;
|
||||
bank_name = gpio_get_bank_info(dev, &num_bits);
|
||||
if (!num_bits)
|
||||
if (!num_bits) {
|
||||
debug("GPIO device %s has no bits\n", dev->name);
|
||||
continue;
|
||||
}
|
||||
banklen = bank_name ? strlen(bank_name) : 0;
|
||||
|
||||
if (!gpio_name || !bank_name ||
|
||||
@ -113,11 +97,12 @@ static int do_gpio_status(bool all, const char *gpio_name)
|
||||
p = gpio_name + banklen;
|
||||
if (gpio_name && *p) {
|
||||
offset = simple_strtoul(p, NULL, 10);
|
||||
show_gpio(dev, bank_name, offset, &flags);
|
||||
gpio_get_description(dev, bank_name, offset,
|
||||
&flags);
|
||||
} else {
|
||||
for (offset = 0; offset < num_bits; offset++) {
|
||||
show_gpio(dev, bank_name, offset,
|
||||
&flags);
|
||||
gpio_get_description(dev, bank_name,
|
||||
offset, &flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -330,6 +330,45 @@ int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
|
||||
return get_function(dev, offset, false, namep);
|
||||
}
|
||||
|
||||
int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
|
||||
{
|
||||
struct dm_gpio_ops *ops = gpio_get_ops(dev);
|
||||
struct gpio_dev_priv *priv;
|
||||
char *str = buf;
|
||||
int func;
|
||||
int ret;
|
||||
int len;
|
||||
|
||||
BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
|
||||
|
||||
*buf = 0;
|
||||
priv = dev->uclass_priv;
|
||||
ret = gpio_get_raw_function(dev, offset, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
func = ret;
|
||||
len = snprintf(str, buffsize, "%s%d: %s",
|
||||
priv->bank_name ? priv->bank_name : "",
|
||||
offset, gpio_function[func]);
|
||||
if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
|
||||
func == GPIOF_UNUSED) {
|
||||
const char *label;
|
||||
bool used;
|
||||
|
||||
ret = ops->get_value(dev, offset);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
|
||||
snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
|
||||
ret,
|
||||
used ? 'x' : ' ',
|
||||
used ? " " : "",
|
||||
label ? label : "");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We need to renumber the GPIOs when any driver is probed/removed */
|
||||
static int gpio_renumber(struct udevice *removed_dev)
|
||||
{
|
||||
|
@ -95,6 +95,24 @@ enum gpio_func_t {
|
||||
|
||||
struct udevice;
|
||||
|
||||
/**
|
||||
* gpio_get_status() - get the current GPIO status as a string
|
||||
*
|
||||
* Obtain the current GPIO status as a string which can be presented to the
|
||||
* user. A typical string is:
|
||||
*
|
||||
* "b4: in: 1 [x] sdmmc_cd"
|
||||
*
|
||||
* which means this is GPIO bank b, offset 4, currently set to input, current
|
||||
* value 1, [x] means that it is requested and the owner is 'sdmmc_cd'
|
||||
*
|
||||
* @dev: Device to check
|
||||
* @offset: Offset of device GPIO to check
|
||||
* @buf: Place to put string
|
||||
* @buffsize: Size of string including \0
|
||||
*/
|
||||
int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize);
|
||||
|
||||
/**
|
||||
* gpio_get_function() - get the current function for a GPIO pin
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user