diff options
Diffstat (limited to 'common/cmd_gpio.c')
| -rw-r--r-- | common/cmd_gpio.c | 129 | 
1 files changed, 116 insertions, 13 deletions
| diff --git a/common/cmd_gpio.c b/common/cmd_gpio.c index 47eee8922..778aa5f09 100644 --- a/common/cmd_gpio.c +++ b/common/cmd_gpio.c @@ -8,7 +8,7 @@  #include <common.h>  #include <command.h> - +#include <dm.h>  #include <asm/gpio.h>  #ifndef name_to_gpio @@ -22,25 +22,115 @@ enum gpio_cmd {  	GPIO_TOGGLE,  }; +#if defined(CONFIG_DM_GPIO) && !defined(gpio_status) +static const char * const gpio_function[] = { +	"input", +	"output", +	"unknown", +}; + +static void show_gpio(struct device *dev, const char *bank_name, int offset) +{ +	struct dm_gpio_ops *ops = gpio_get_ops(dev); +	char buf[80]; +	int ret; + +	*buf = '\0'; +	if (ops->get_state) { +		ret = ops->get_state(dev, offset, buf, sizeof(buf)); +		if (ret) { +			puts("<unknown>"); +			return; +		} +	} else { +		int func =  GPIOF_UNKNOWN; +		int ret; + +		if (ops->get_function) { +			ret = ops->get_function(dev, offset); +			if (ret >= 0 && ret < ARRAY_SIZE(gpio_function)) +				func = ret; +		} +		sprintf(buf, "%s%u: %8s %d", bank_name, offset, +			gpio_function[func], ops->get_value(dev, offset)); +	} + +	puts(buf); +	puts("\n"); +} + +static int do_gpio_status(const char *gpio_name) +{ +	struct device *dev; +	int newline = 0; +	int ret; + +	if (gpio_name && !*gpio_name) +		gpio_name = NULL; +	for (ret = uclass_first_device(UCLASS_GPIO, &dev); +	     dev; +	     ret = uclass_next_device(&dev)) { +		const char *bank_name; +		int num_bits; + +		bank_name = gpio_get_bank_info(dev, &num_bits); + +		if (!gpio_name || !bank_name || +		    !strncmp(gpio_name, bank_name, strlen(bank_name))) { +			const char *p = NULL; +			int offset; + +			if (bank_name) { +				if (newline) +					putc('\n'); +				printf("Bank %s:\n", bank_name); +			} +			newline = 1; +			if (gpio_name && bank_name) { +				p = gpio_name + strlen(bank_name); +				offset = simple_strtoul(p, NULL, 10); +				show_gpio(dev, bank_name, offset); +			} else { +				for (offset = 0; offset < num_bits; offset++) +					show_gpio(dev, bank_name, offset); +			} +		} +	} + +	return ret; +} +#endif +  static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  { -	int gpio; +	unsigned int gpio;  	enum gpio_cmd sub_cmd;  	ulong value; -	const char *str_cmd, *str_gpio; +	const char *str_cmd, *str_gpio = NULL; +#ifdef CONFIG_DM_GPIO +	int ret; +#endif +	if (argc < 2) + show_usage: +		return CMD_RET_USAGE; +	str_cmd = argv[1]; +	if (argc > 2) +		str_gpio = argv[2]; +	if (!strcmp(str_cmd, "status")) { +		/* Support deprecated gpio_status() */  #ifdef gpio_status -	if (argc == 2 && !strcmp(argv[1], "status")) {  		gpio_status();  		return 0; -	} +#elif defined(CONFIG_DM_GPIO) +		return cmd_process_error(cmdtp, do_gpio_status(str_gpio)); +#else +		goto show_usage;  #endif +	} -	if (argc != 3) - show_usage: -		return CMD_RET_USAGE; -	str_cmd = argv[1]; -	str_gpio = argv[2]; +	if (!str_gpio) +		goto show_usage;  	/* parse the behavior */  	switch (*str_cmd) { @@ -51,11 +141,23 @@ static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  		default:  goto show_usage;  	} +#if defined(CONFIG_DM_GPIO) +	/* +	 * TODO(sjg@chromium.org): For now we must fit into the existing GPIO +	 * framework, so we look up the name here and convert it to a GPIO number. +	 * Once all GPIO drivers are converted to driver model, we can change the +	 * code here to use the GPIO uclass interface instead of the numbered +	 * GPIO compatibility layer. +	 */ +	ret = gpio_lookup_name(str_gpio, NULL, NULL, &gpio); +	if (ret) +		return cmd_process_error(cmdtp, ret); +#else  	/* turn the gpio name into a gpio number */  	gpio = name_to_gpio(str_gpio);  	if (gpio < 0)  		goto show_usage; - +#endif  	/* grab the pin before we tweak it */  	if (gpio_request(gpio, "cmd_gpio")) {  		printf("gpio: requesting pin %u failed\n", gpio); @@ -84,6 +186,7 @@ static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  }  U_BOOT_CMD(gpio, 3, 0, do_gpio, -	"input/set/clear/toggle gpio pins", +	"query and control gpio pins",  	"<input|set|clear|toggle> <pin>\n" -	"    - input/set/clear/toggle the specified pin"); +	"    - input/set/clear/toggle the specified pin\n" +	"gpio status [<bank> | <pin>]"); |