exynos/s5p: Add helper function for reading a single MVL3 GPIO
This adds a helper function to read only a single GPIO which uses 3-state logic. Examples of this typically include board straps which are used to provide mainboard-specific information at the hardware- level, such as board revision or configuration options. This is part of a larger clean-up effort for Snow. We may want to genericise this for other CPUs in the future. Change-Id: Ic44f5e589cda89b419a07eca246847e9ce7dcd8d Signed-off-by: David Hendricks <dhendrix@chromium.org> Reviewed-on: http://review.coreboot.org/2266 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
		
				
					committed by
					
						 Ronald G. Minnich
						Ronald G. Minnich
					
				
			
			
				
	
			
			
			
						parent
						
							d58ba2add4
						
					
				
				
					commit
					ad7f98cb01
				
			| @@ -477,6 +477,15 @@ void gpio_set_rate(int gpio, int mode); | ||||
|  */ | ||||
| int gpio_decode_number(unsigned gpio_list[], int count); | ||||
|  | ||||
| /* | ||||
|  * similar to gpio_decode_number, but reads only a single GPIO | ||||
|  * | ||||
|  * @param gpio		GPIO to read | ||||
|  * @return -1 if the value cannot be determined. Otherwise returns | ||||
|  *              the corresponding MVL3 enum value. | ||||
|  */ | ||||
| int gpio_read_mvl3(unsigned gpio); | ||||
|  | ||||
| void gpio_info(void); | ||||
|  | ||||
| #endif	/* EXYNOS5250_GPIO_H_ */ | ||||
|   | ||||
| @@ -21,6 +21,7 @@ | ||||
| /* FIXME(dhendrix): fix this up so it doesn't require a bunch of #ifdefs... */ | ||||
| #include <common.h> | ||||
| //#include <arch/io.h> | ||||
| #include <gpio.h> | ||||
| #include <arch/gpio.h> | ||||
| #include <console/console.h> | ||||
| #include <cpu/samsung/s5p-common/gpio.h> | ||||
| @@ -414,42 +415,61 @@ int gpio_set_value(unsigned gpio, int value) | ||||
|  */ | ||||
| #define GPIO_DELAY_US 5 | ||||
|  | ||||
| /* FIXME(dhendrix): this should probably go to a more generic location */ | ||||
| int gpio_read_mvl3(unsigned gpio) | ||||
| { | ||||
| 	int high, low; | ||||
| 	enum mvl3 value; | ||||
|  | ||||
| 	if (gpio >= GPIO_MAX_PORT) | ||||
| 		return -1; | ||||
|  | ||||
| 	gpio_direction_input(gpio); | ||||
| 	gpio_set_pull(gpio, EXYNOS_GPIO_PULL_UP); | ||||
| 	udelay(GPIO_DELAY_US); | ||||
| 	high = gpio_get_value(gpio); | ||||
| 	gpio_set_pull(gpio, EXYNOS_GPIO_PULL_DOWN); | ||||
| 	udelay(GPIO_DELAY_US); | ||||
| 	low = gpio_get_value(gpio); | ||||
|  | ||||
| 	if (high && low) /* external pullup */ | ||||
| 		value = LOGIC_1; | ||||
| 	else if (!high && !low) /* external pulldown */ | ||||
| 		value = LOGIC_0; | ||||
| 	else /* floating */ | ||||
| 		value = LOGIC_Z; | ||||
|  | ||||
| 	/* | ||||
| 	 * Check if line is externally pulled high and | ||||
| 	 * configure the internal pullup to match.  For | ||||
| 	 * floating and pulldowns, the GPIO is already | ||||
| 	 * configured with an internal pulldown from the | ||||
| 	 * above test. | ||||
| 	 */ | ||||
| 	if (value == LOGIC_1) | ||||
| 		gpio_set_pull(gpio, EXYNOS_GPIO_PULL_UP); | ||||
|  | ||||
| 	return value; | ||||
| } | ||||
|  | ||||
| int gpio_decode_number(unsigned gpio_list[], int count) | ||||
| { | ||||
| 	int result = 0; | ||||
| 	int multiplier = 1; | ||||
| 	int value, high, low; | ||||
| 	int gpio, i; | ||||
| 	int gpio, i, value; | ||||
| 	enum mvl3 mvl3; | ||||
|  | ||||
| 	for (i = 0; i < count; i++) { | ||||
| 		gpio = gpio_list[i]; | ||||
| 		if (gpio >= GPIO_MAX_PORT) | ||||
| 			return -1; | ||||
| 		gpio_direction_input(gpio); | ||||
| 		gpio_set_pull(gpio, EXYNOS_GPIO_PULL_UP); | ||||
| 		udelay(GPIO_DELAY_US); | ||||
| 		high = gpio_get_value(gpio); | ||||
| 		gpio_set_pull(gpio, EXYNOS_GPIO_PULL_DOWN); | ||||
| 		udelay(GPIO_DELAY_US); | ||||
| 		low = gpio_get_value(gpio); | ||||
|  | ||||
| 		if (high && low) /* external pullup */ | ||||
| 		mvl3 = gpio_read_mvl3(gpio); | ||||
| 		if (mvl3 == LOGIC_1) | ||||
| 			value = 2; | ||||
| 		else if (!high && !low) /* external pulldown */ | ||||
| 		else if (mvl3 == LOGIC_0) | ||||
| 			value = 1; | ||||
| 		else /* floating */ | ||||
| 		else if (mvl3 == LOGIC_Z) | ||||
| 			value = 0; | ||||
|  | ||||
| 		/* | ||||
| 		 * Check if line is externally pulled high and | ||||
| 		 * configure the internal pullup to match.  For | ||||
| 		 * floating and pulldowns, the GPIO is already | ||||
| 		 * configured with an internal pulldown from the | ||||
| 		 * above test. | ||||
| 		 */ | ||||
| 		if (value == 2) | ||||
| 			gpio_set_pull(gpio, EXYNOS_GPIO_PULL_UP); | ||||
| 		else | ||||
| 			return -1; | ||||
|  | ||||
| 		result += value * multiplier; | ||||
| 		multiplier *= 3; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user