From ad7f98cb0163d0ef2b0e6f75d334cdbd6faf846c Mon Sep 17 00:00:00 2001 From: David Hendricks Date: Sat, 2 Feb 2013 17:02:36 -0800 Subject: 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 Reviewed-on: http://review.coreboot.org/2266 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich --- src/cpu/samsung/exynos5250/gpio.h | 9 +++++ src/cpu/samsung/s5p-common/s5p_gpio.c | 70 ++++++++++++++++++++++------------- 2 files changed, 54 insertions(+), 25 deletions(-) (limited to 'src/cpu/samsung') diff --git a/src/cpu/samsung/exynos5250/gpio.h b/src/cpu/samsung/exynos5250/gpio.h index 7606262062..12143849f5 100644 --- a/src/cpu/samsung/exynos5250/gpio.h +++ b/src/cpu/samsung/exynos5250/gpio.h @@ -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_ */ diff --git a/src/cpu/samsung/s5p-common/s5p_gpio.c b/src/cpu/samsung/s5p-common/s5p_gpio.c index 50c451974c..f09d0a4ee5 100644 --- a/src/cpu/samsung/s5p-common/s5p_gpio.c +++ b/src/cpu/samsung/s5p-common/s5p_gpio.c @@ -21,6 +21,7 @@ /* FIXME(dhendrix): fix this up so it doesn't require a bunch of #ifdefs... */ #include //#include +#include #include #include #include @@ -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; -- cgit v1.2.3