David Hendricks (dhendrix@chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2266
-gerrit
commit 94c3b0a80f06d974a2b3eadaa31b5340dc43601a Author: David Hendricks dhendrix@chromium.org Date: Sat Feb 2 17:02:36 2013 -0800
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 --- src/cpu/samsung/exynos5250/gpio.h | 9 +++++ src/cpu/samsung/s5p-common/s5p_gpio.c | 69 ++++++++++++++++++++++------------- 2 files changed, 53 insertions(+), 25 deletions(-)
diff --git a/src/cpu/samsung/exynos5250/gpio.h b/src/cpu/samsung/exynos5250/gpio.h index 7606262..1214384 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 50c4519..8332015 100644 --- a/src/cpu/samsung/s5p-common/s5p_gpio.c +++ b/src/cpu/samsung/s5p-common/s5p_gpio.c @@ -414,42 +414,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;