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:
parent
ea562257f8
commit
9fb7070621
@ -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);
|
||||
}
|
||||
|
@ -65,6 +65,11 @@
|
||||
};
|
||||
};
|
||||
|
||||
i2c-arbitrator {
|
||||
freebsd,our-gpio = <177>;
|
||||
freebsd,ec-gpio = <168>;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdin = &serial2;
|
||||
stdout = &serial2;
|
||||
|
Loading…
Reference in New Issue
Block a user