Describe I2C arbitrator device in DTS and use it for Chromebook Snow only.

Submitted by:	Maxim Ignatenko <gelraen.ua@gmail.com>
This commit is contained in:
br 2014-05-28 06:11:12 +00:00
parent ea562257f8
commit 9fb7070621
2 changed files with 53 additions and 11 deletions

View File

@ -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);
}

View File

@ -65,6 +65,11 @@
};
};
i2c-arbitrator {
freebsd,our-gpio = <177>;
freebsd,ec-gpio = <168>;
};
chosen {
stdin = &serial2;
stdout = &serial2;