Merge git://git.denx.de/u-boot-dm
This commit is contained in:
		
						commit
						141e1faec2
					
				|  | @ -113,4 +113,12 @@ | ||||||
| 			0x070b0067 0x070c0069>; | 			0x070b0067 0x070c0069>; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
|  | 	gpio_a: gpios { | ||||||
|  | 		gpio-controller; | ||||||
|  | 		compatible = "sandbox,gpio"; | ||||||
|  | 		#gpio-cells = <1>; | ||||||
|  | 		gpio-bank-name = "a"; | ||||||
|  | 		num-gpios = <20>; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -8,6 +8,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <common.h> | #include <common.h> | ||||||
| #include <command.h> | #include <command.h> | ||||||
|  | #include <errno.h> | ||||||
| #include <dm.h> | #include <dm.h> | ||||||
| #include <asm/gpio.h> | #include <asm/gpio.h> | ||||||
| 
 | 
 | ||||||
|  | @ -24,18 +25,46 @@ enum gpio_cmd { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #if defined(CONFIG_DM_GPIO) && !defined(gpio_status) | #if defined(CONFIG_DM_GPIO) && !defined(gpio_status) | ||||||
| static const char * const gpio_function[] = { | static const char * const gpio_function[GPIOF_COUNT] = { | ||||||
| 	"input", | 	"input", | ||||||
| 	"output", | 	"output", | ||||||
|  | 	"unused", | ||||||
| 	"unknown", | 	"unknown", | ||||||
|  | 	"func", | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static void show_gpio(struct udevice *dev, const char *bank_name, int offset) | /* A few flags used by show_gpio() */ | ||||||
|  | enum { | ||||||
|  | 	FLAG_SHOW_ALL		= 1 << 0, | ||||||
|  | 	FLAG_SHOW_BANK		= 1 << 1, | ||||||
|  | 	FLAG_SHOW_NEWLINE	= 1 << 2, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static void show_gpio(struct udevice *dev, const char *bank_name, int offset, | ||||||
|  | 		      int *flagsp) | ||||||
| { | { | ||||||
| 	struct dm_gpio_ops *ops = gpio_get_ops(dev); | 	struct dm_gpio_ops *ops = gpio_get_ops(dev); | ||||||
|  | 	int func = GPIOF_UNKNOWN; | ||||||
| 	char buf[80]; | 	char buf[80]; | ||||||
| 	int ret; | 	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) | ||||||
|  | 		return; | ||||||
|  | 	if ((*flagsp & FLAG_SHOW_BANK) && bank_name) { | ||||||
|  | 		if (*flagsp & FLAG_SHOW_NEWLINE) { | ||||||
|  | 			putc('\n'); | ||||||
|  | 			*flagsp &= ~FLAG_SHOW_NEWLINE; | ||||||
|  | 		} | ||||||
|  | 		printf("Bank %s:\n", bank_name); | ||||||
|  | 		*flagsp &= ~FLAG_SHOW_BANK; | ||||||
|  | 	} | ||||||
| 	*buf = '\0'; | 	*buf = '\0'; | ||||||
| 	if (ops->get_state) { | 	if (ops->get_state) { | ||||||
| 		ret = ops->get_state(dev, offset, buf, sizeof(buf)); | 		ret = ops->get_state(dev, offset, buf, sizeof(buf)); | ||||||
|  | @ -44,14 +73,6 @@ static void show_gpio(struct udevice *dev, const char *bank_name, int offset) | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} 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, | 		sprintf(buf, "%s%u: %8s %d", bank_name, offset, | ||||||
| 			gpio_function[func], ops->get_value(dev, offset)); | 			gpio_function[func], ops->get_value(dev, offset)); | ||||||
| 	} | 	} | ||||||
|  | @ -60,12 +81,14 @@ static void show_gpio(struct udevice *dev, const char *bank_name, int offset) | ||||||
| 	puts("\n"); | 	puts("\n"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int do_gpio_status(const char *gpio_name) | static int do_gpio_status(bool all, const char *gpio_name) | ||||||
| { | { | ||||||
| 	struct udevice *dev; | 	struct udevice *dev; | ||||||
| 	int newline = 0; | 	int banklen; | ||||||
|  | 	int flags; | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
|  | 	flags = 0; | ||||||
| 	if (gpio_name && !*gpio_name) | 	if (gpio_name && !*gpio_name) | ||||||
| 		gpio_name = NULL; | 		gpio_name = NULL; | ||||||
| 	for (ret = uclass_first_device(UCLASS_GPIO, &dev); | 	for (ret = uclass_first_device(UCLASS_GPIO, &dev); | ||||||
|  | @ -74,29 +97,34 @@ static int do_gpio_status(const char *gpio_name) | ||||||
| 		const char *bank_name; | 		const char *bank_name; | ||||||
| 		int num_bits; | 		int num_bits; | ||||||
| 
 | 
 | ||||||
|  | 		flags |= FLAG_SHOW_BANK; | ||||||
|  | 		if (all) | ||||||
|  | 			flags |= FLAG_SHOW_ALL; | ||||||
| 		bank_name = gpio_get_bank_info(dev, &num_bits); | 		bank_name = gpio_get_bank_info(dev, &num_bits); | ||||||
|  | 		if (!num_bits) | ||||||
|  | 			continue; | ||||||
|  | 		banklen = bank_name ? strlen(bank_name) : 0; | ||||||
| 
 | 
 | ||||||
| 		if (!gpio_name || !bank_name || | 		if (!gpio_name || !bank_name || | ||||||
| 		    !strncmp(gpio_name, bank_name, strlen(bank_name))) { | 		    !strncmp(gpio_name, bank_name, banklen)) { | ||||||
| 			const char *p = NULL; | 			const char *p = NULL; | ||||||
| 			int offset; | 			int offset; | ||||||
| 
 | 
 | ||||||
| 			if (bank_name) { | 			p = gpio_name + banklen; | ||||||
| 				if (newline) | 			if (gpio_name && *p) { | ||||||
| 					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); | 				offset = simple_strtoul(p, NULL, 10); | ||||||
| 				show_gpio(dev, bank_name, offset); | 				show_gpio(dev, bank_name, offset, &flags); | ||||||
| 			} else { | 			} else { | ||||||
| 				for (offset = 0; offset < num_bits; offset++) | 				for (offset = 0; offset < num_bits; offset++) { | ||||||
| 					show_gpio(dev, bank_name, offset); | 					show_gpio(dev, bank_name, offset, | ||||||
|  | 						  &flags); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		/* Add a newline between bank names */ | ||||||
|  | 		if (!(flags & FLAG_SHOW_BANK)) | ||||||
|  | 			flags |= FLAG_SHOW_NEWLINE; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
|  | @ -108,23 +136,33 @@ static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | ||||||
| 	enum gpio_cmd sub_cmd; | 	enum gpio_cmd sub_cmd; | ||||||
| 	ulong value; | 	ulong value; | ||||||
| 	const char *str_cmd, *str_gpio = NULL; | 	const char *str_cmd, *str_gpio = NULL; | ||||||
| #ifdef CONFIG_DM_GPIO |  | ||||||
| 	int ret; | 	int ret; | ||||||
|  | #ifdef CONFIG_DM_GPIO | ||||||
|  | 	bool all = false; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	if (argc < 2) | 	if (argc < 2) | ||||||
|  show_usage: |  show_usage: | ||||||
| 		return CMD_RET_USAGE; | 		return CMD_RET_USAGE; | ||||||
| 	str_cmd = argv[1]; | 	str_cmd = argv[1]; | ||||||
| 	if (argc > 2) | 	argc -= 2; | ||||||
| 		str_gpio = argv[2]; | 	argv += 2; | ||||||
|  | #ifdef CONFIG_DM_GPIO | ||||||
|  | 	if (argc > 0 && !strcmp(*argv, "-a")) { | ||||||
|  | 		all = true; | ||||||
|  | 		argc--; | ||||||
|  | 		argv++; | ||||||
|  | 	} | ||||||
|  | #endif | ||||||
|  | 	if (argc > 0) | ||||||
|  | 		str_gpio = *argv; | ||||||
| 	if (!strcmp(str_cmd, "status")) { | 	if (!strcmp(str_cmd, "status")) { | ||||||
| 		/* Support deprecated gpio_status() */ | 		/* Support deprecated gpio_status() */ | ||||||
| #ifdef gpio_status | #ifdef gpio_status | ||||||
| 		gpio_status(); | 		gpio_status(); | ||||||
| 		return 0; | 		return 0; | ||||||
| #elif defined(CONFIG_DM_GPIO) | #elif defined(CONFIG_DM_GPIO) | ||||||
| 		return cmd_process_error(cmdtp, do_gpio_status(str_gpio)); | 		return cmd_process_error(cmdtp, do_gpio_status(all, str_gpio)); | ||||||
| #else | #else | ||||||
| 		goto show_usage; | 		goto show_usage; | ||||||
| #endif | #endif | ||||||
|  | @ -160,7 +198,8 @@ static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | ||||||
| 		goto show_usage; | 		goto show_usage; | ||||||
| #endif | #endif | ||||||
| 	/* grab the pin before we tweak it */ | 	/* grab the pin before we tweak it */ | ||||||
| 	if (gpio_request(gpio, "cmd_gpio")) { | 	ret = gpio_request(gpio, "cmd_gpio"); | ||||||
|  | 	if (ret && ret != -EBUSY) { | ||||||
| 		printf("gpio: requesting pin %u failed\n", gpio); | 		printf("gpio: requesting pin %u failed\n", gpio); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  | @ -181,13 +220,14 @@ static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | ||||||
| 	printf("gpio: pin %s (gpio %i) value is %lu\n", | 	printf("gpio: pin %s (gpio %i) value is %lu\n", | ||||||
| 		str_gpio, gpio, value); | 		str_gpio, gpio, value); | ||||||
| 
 | 
 | ||||||
|  | 	if (ret != -EBUSY) | ||||||
| 		gpio_free(gpio); | 		gpio_free(gpio); | ||||||
| 
 | 
 | ||||||
| 	return value; | 	return value; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| U_BOOT_CMD(gpio, 3, 0, do_gpio, | U_BOOT_CMD(gpio, 4, 0, do_gpio, | ||||||
| 	   "query and control gpio pins", | 	   "query and control gpio pins", | ||||||
| 	   "<input|set|clear|toggle> <pin>\n" | 	   "<input|set|clear|toggle> <pin>\n" | ||||||
| 	   "    - input/set/clear/toggle the specified pin\n" | 	   "    - input/set/clear/toggle the specified pin\n" | ||||||
| 	"gpio status [<bank> | <pin>]"); | 	   "gpio status [-a] [<bank> | <pin>]  - show [all/claimed] GPIOs"); | ||||||
|  |  | ||||||
|  | @ -79,11 +79,15 @@ int gpio_get_value(unsigned gpio); | ||||||
|  */ |  */ | ||||||
| int gpio_set_value(unsigned gpio, int value); | int gpio_set_value(unsigned gpio, int value); | ||||||
| 
 | 
 | ||||||
| /* State of a GPIO, as reported by get_state() */ | /* State of a GPIO, as reported by get_function() */ | ||||||
| enum { | enum { | ||||||
| 	GPIOF_INPUT = 0, | 	GPIOF_INPUT = 0, | ||||||
| 	GPIOF_OUTPUT, | 	GPIOF_OUTPUT, | ||||||
| 	GPIOF_UNKNOWN, | 	GPIOF_UNUSED,		/* Not claimed */ | ||||||
|  | 	GPIOF_UNKNOWN,		/* Not known */ | ||||||
|  | 	GPIOF_FUNC,		/* Not used as a GPIO */ | ||||||
|  | 
 | ||||||
|  | 	GPIOF_COUNT, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct udevice; | struct udevice; | ||||||
|  | @ -123,6 +127,13 @@ struct dm_gpio_ops { | ||||||
| 				int value); | 				int value); | ||||||
| 	int (*get_value)(struct udevice *dev, unsigned offset); | 	int (*get_value)(struct udevice *dev, unsigned offset); | ||||||
| 	int (*set_value)(struct udevice *dev, unsigned offset, int value); | 	int (*set_value)(struct udevice *dev, unsigned offset, int value); | ||||||
|  | 	/**
 | ||||||
|  | 	 * get_function() Get the GPIO function | ||||||
|  | 	 * | ||||||
|  | 	 * @dev:     Device to check | ||||||
|  | 	 * @offset:  GPIO offset within that device | ||||||
|  | 	 * @return current function - GPIOF_... | ||||||
|  | 	 */ | ||||||
| 	int (*get_function)(struct udevice *dev, unsigned offset); | 	int (*get_function)(struct udevice *dev, unsigned offset); | ||||||
| 	int (*get_state)(struct udevice *dev, unsigned offset, char *state, | 	int (*get_state)(struct udevice *dev, unsigned offset, char *state, | ||||||
| 			 int maxlen); | 			 int maxlen); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue