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>
This commit is contained in:
parent
d58ba2add4
commit
ad7f98cb01
|
@ -477,6 +477,15 @@ void gpio_set_rate(int gpio, int mode);
|
||||||
*/
|
*/
|
||||||
int gpio_decode_number(unsigned gpio_list[], int count);
|
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);
|
void gpio_info(void);
|
||||||
|
|
||||||
#endif /* EXYNOS5250_GPIO_H_ */
|
#endif /* EXYNOS5250_GPIO_H_ */
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
/* FIXME(dhendrix): fix this up so it doesn't require a bunch of #ifdefs... */
|
/* FIXME(dhendrix): fix this up so it doesn't require a bunch of #ifdefs... */
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
//#include <arch/io.h>
|
//#include <arch/io.h>
|
||||||
|
#include <gpio.h>
|
||||||
#include <arch/gpio.h>
|
#include <arch/gpio.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <cpu/samsung/s5p-common/gpio.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
|
#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 gpio_decode_number(unsigned gpio_list[], int count)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int multiplier = 1;
|
int multiplier = 1;
|
||||||
int value, high, low;
|
int gpio, i, value;
|
||||||
int gpio, i;
|
enum mvl3 mvl3;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
gpio = gpio_list[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;
|
value = 2;
|
||||||
else if (!high && !low) /* external pulldown */
|
else if (mvl3 == LOGIC_0)
|
||||||
value = 1;
|
value = 1;
|
||||||
else /* floating */
|
else if (mvl3 == LOGIC_Z)
|
||||||
value = 0;
|
value = 0;
|
||||||
|
else
|
||||||
/*
|
return -1;
|
||||||
* 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);
|
|
||||||
|
|
||||||
result += value * multiplier;
|
result += value * multiplier;
|
||||||
multiplier *= 3;
|
multiplier *= 3;
|
||||||
|
|
Loading…
Reference in New Issue