summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Hendricks <dhendrix@chromium.org>2013-02-02 17:02:36 -0800
committerRonald G. Minnich <rminnich@gmail.com>2013-02-04 05:52:18 +0100
commitad7f98cb0163d0ef2b0e6f75d334cdbd6faf846c (patch)
treede951e1d1737eb6a2f3112c299a9c47679d8d3af
parentd58ba2add4b0ae955126ca746db39aa9fa98fd9f (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.h9
-rw-r--r--src/cpu/samsung/s5p-common/s5p_gpio.c70
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;