diff options
author | David Hendricks <dhendrix@chromium.org> | 2013-02-02 17:02:36 -0800 |
---|---|---|
committer | Ronald G. Minnich <rminnich@gmail.com> | 2013-02-04 05:52:18 +0100 |
commit | ad7f98cb0163d0ef2b0e6f75d334cdbd6faf846c (patch) | |
tree | de951e1d1737eb6a2f3112c299a9c47679d8d3af | |
parent | d58ba2add4b0ae955126ca746db39aa9fa98fd9f (diff) |
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>
-rw-r--r-- | src/cpu/samsung/exynos5250/gpio.h | 9 | ||||
-rw-r--r-- | src/cpu/samsung/s5p-common/s5p_gpio.c | 70 |
2 files changed, 54 insertions, 25 deletions
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 <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; |