summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/arm/samsung/exynos/chrome_ec.c59
-rw-r--r--sys/boot/fdt/dts/arm/exynos5250-chromebook-snow.dts5
2 files changed, 53 insertions, 11 deletions
diff --git a/sys/arm/samsung/exynos/chrome_ec.c b/sys/arm/samsung/exynos/chrome_ec.c
index 5ef64ee..7aa28bd 100644
--- a/sys/arm/samsung/exynos/chrome_ec.c
+++ b/sys/arm/samsung/exynos/chrome_ec.c
@@ -60,12 +60,11 @@ __FBSDID("$FreeBSD$");
#include <arm/samsung/exynos/chrome_ec.h>
-/* TODO: export to DTS */
-#define OUR_GPIO 177
-#define EC_GPIO 168
-
struct ec_softc {
device_t dev;
+ int have_arbitrator;
+ pcell_t our_gpio;
+ pcell_t ec_gpio;
};
struct ec_softc *ec_sc;
@@ -82,17 +81,24 @@ bus_claim(struct ec_softc *sc)
device_t gpio_dev;
int status;
+ if (sc->our_gpio == 0 || sc->ec_gpio == 0) {
+ device_printf(sc->dev, "i2c arbitrator is not configured\n");
+ return (1);
+ }
+
gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
- if (gpio_dev == NULL) {
+ if (gpio_dev == NULL) {
device_printf(sc->dev, "cant find gpio_dev\n");
return (1);
}
/* Say we want the bus */
- GPIO_PIN_SET(gpio_dev, OUR_GPIO, GPIO_PIN_LOW);
+ GPIO_PIN_SET(gpio_dev, sc->our_gpio, GPIO_PIN_LOW);
+
+ /* TODO(imax): insert a delay to allow EC to react. */
/* Check EC decision */
- GPIO_PIN_GET(gpio_dev, EC_GPIO, &status);
+ GPIO_PIN_GET(gpio_dev, sc->ec_gpio, &status);
if (status == 1) {
/* Okay. We have bus */
@@ -108,13 +114,18 @@ bus_release(struct ec_softc *sc)
{
device_t gpio_dev;
+ if (sc->our_gpio == 0 || sc->ec_gpio == 0) {
+ device_printf(sc->dev, "i2c arbitrator is not configured\n");
+ return (1);
+ }
+
gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
- if (gpio_dev == NULL) {
+ if (gpio_dev == NULL) {
device_printf(sc->dev, "cant find gpio_dev\n");
return (1);
}
- GPIO_PIN_SET(gpio_dev, OUR_GPIO, GPIO_PIN_HIGH);
+ GPIO_PIN_SET(gpio_dev, sc->our_gpio, GPIO_PIN_HIGH);
return (0);
}
@@ -209,6 +220,28 @@ int ec_hello(void)
return (0);
}
+static void
+configure_i2c_arbitrator(struct ec_softc *sc)
+{
+ phandle_t arbitrator;
+
+ /* TODO(imax): look for compatible entry instead of hard-coded path */
+ arbitrator = OF_finddevice("/i2c-arbitrator");
+ if (arbitrator > 0 &&
+ OF_hasprop(arbitrator, "freebsd,our-gpio") &&
+ OF_hasprop(arbitrator, "freebsd,ec-gpio")) {
+ sc->have_arbitrator = 1;
+ OF_getencprop(arbitrator, "freebsd,our-gpio",
+ &sc->our_gpio, sizeof(sc->our_gpio));
+ OF_getencprop(arbitrator, "freebsd,ec-gpio",
+ &sc->ec_gpio, sizeof(sc->ec_gpio));
+ } else {
+ sc->have_arbitrator = 0;
+ sc->our_gpio = 0;
+ sc->ec_gpio = 0;
+ }
+}
+
static int
ec_attach(device_t dev)
{
@@ -219,6 +252,8 @@ ec_attach(device_t dev)
ec_sc = sc;
+ configure_i2c_arbitrator(sc);
+
/*
* Claim the bus.
*
@@ -227,7 +262,7 @@ ec_attach(device_t dev)
*
*/
- if (bus_claim(sc) != 0) {
+ if (sc->have_arbitrator && bus_claim(sc) != 0) {
return (ENXIO);
}
@@ -241,7 +276,9 @@ ec_detach(device_t dev)
sc = device_get_softc(dev);
- bus_release(sc);
+ if (sc->have_arbitrator) {
+ bus_release(sc);
+ }
return (0);
}
diff --git a/sys/boot/fdt/dts/arm/exynos5250-chromebook-snow.dts b/sys/boot/fdt/dts/arm/exynos5250-chromebook-snow.dts
index 051b9d4..f7dc3f9 100644
--- a/sys/boot/fdt/dts/arm/exynos5250-chromebook-snow.dts
+++ b/sys/boot/fdt/dts/arm/exynos5250-chromebook-snow.dts
@@ -65,6 +65,11 @@
};
};
+ i2c-arbitrator {
+ freebsd,our-gpio = <177>;
+ freebsd,ec-gpio = <168>;
+ };
+
chosen {
stdin = &serial2;
stdout = &serial2;
OpenPOWER on IntegriCloud