diff options
Diffstat (limited to 'src')
-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; |