Esempio n. 1
0
void
kiic_attach(struct device *parent, struct device *self, void *aux)
{
	struct kiic_softc *sc = (struct kiic_softc *)self;
	struct confargs *ca = aux;
	int node = ca->ca_node;
	int rate, count = 0;
	char name[32];

	ca->ca_reg[0] += ca->ca_baseaddr;

	if (OF_getprop(node, "AAPL,i2c-rate", &rate, 4) != 4) {
		printf(": cannot get i2c-rate\n");
		return;
	}
	if (OF_getprop(node, "AAPL,address", &sc->sc_paddr, 4) != 4) {
		printf(": unable to find i2c address\n");
		return;
	}
	if (OF_getprop(node, "AAPL,address-step", &sc->sc_regstep, 4) != 4) {
		printf(": unable to find i2c address step\n");
		return;
	}
	sc->sc_reg = mapiodev(sc->sc_paddr, (DATA+1)*sc->sc_regstep);

	printf("\n");

	kiic_writereg(sc, STATUS, 0);
	kiic_writereg(sc, ISR, 0);
	kiic_writereg(sc, IER, 0);

	kiic_setmode(sc, I2C_STDSUBMODE, 0);
	kiic_setspeed(sc, I2C_100kHz);		/* XXX rate */

	rw_init(&sc->sc_buslock, sc->sc_dev.dv_xname);
	kiic_writereg(sc, IER,I2C_INT_DATA|I2C_INT_ADDR|I2C_INT_STOP);

	for (node = OF_child(ca->ca_node); node; node = OF_peer(node)) {
		if (OF_getprop(node, "name", &name, sizeof name) > 0) {
			if (strcmp(name, "i2c-bus") == 0) {
				kiic_attach_bus(sc, &sc->sc_bus[count], node);
				if (++count >= KIIC_MAX_BUSSES)
					break;
			}
		}
	}

	/* 
	 * If we didn't find any i2c-bus nodes, there is only a single
	 * i2c bus.
	 */

	if (count == 0)
		kiic_attach_bus(sc, &sc->sc_bus[0], ca->ca_node);
}
Esempio n. 2
0
static int
kiic_attach(device_t self)
{
	struct kiic_softc *sc = device_get_softc(self);
	int rid, rate;
	phandle_t node;
	char name[64];

	bzero(sc, sizeof(*sc));
	sc->sc_dev = self;
	
	node = ofw_bus_get_node(self);
	if (node == 0 || node == -1) {
		return (EINVAL);
	}

	rid = 0;
	sc->sc_reg = bus_alloc_resource_any(self, SYS_RES_MEMORY,
			&rid, RF_ACTIVE);
	if (sc->sc_reg == NULL) {
		return (ENOMEM);
	}

	if (OF_getencprop(node, "AAPL,i2c-rate", &rate, 4) != 4) {
		device_printf(self, "cannot get i2c-rate\n");
		return (ENXIO);
	}
	if (OF_getencprop(node, "AAPL,address-step", &sc->sc_regstep, 4) != 4) {
		device_printf(self, "unable to find i2c address step\n");
		return (ENXIO);
	}

	/*
	 * Some Keywest I2C devices have their children attached directly
	 * underneath them.  Some have a single 'iicbus' child with the
	 * devices underneath that.  Sort this out, and make sure that the
	 * OFW I2C layer has the correct node.
	 *
	 * Note: the I2C children of the Uninorth bridges have two ports.
	 *  In general, the port is designated in the 9th bit of the I2C
	 *  address. However, for kiic devices with children attached below
	 *  an i2c-bus node, the port is indicated in the 'reg' property
	 *  of the i2c-bus node.
	 */

	sc->sc_node = node;

	node = OF_child(node);
	if (OF_getprop(node, "name", name, sizeof(name)) > 0) {
		if (strcmp(name,"i2c-bus") == 0) {
			phandle_t reg;
			if (OF_getprop(node, "reg", &reg, sizeof(reg)) > 0)
				sc->sc_i2c_base = reg << 8;

			sc->sc_node = node;
		}
	}

	mtx_init(&sc->sc_mutex, "kiic", NULL, MTX_DEF);

	sc->sc_irq = bus_alloc_resource_any(self, SYS_RES_IRQ, &sc->sc_irqrid, 
	    RF_ACTIVE);
	bus_setup_intr(self, sc->sc_irq, INTR_TYPE_MISC | INTR_MPSAFE, NULL,
	    kiic_intr, sc, &sc->sc_ih);

	kiic_writereg(sc, ISR, kiic_readreg(sc, ISR));
	kiic_writereg(sc, STATUS, 0);
	kiic_writereg(sc, IER, 0);

	kiic_setmode(sc, I2C_STDMODE);
	kiic_setspeed(sc, I2C_100kHz);		/* XXX rate */
	
	kiic_writereg(sc, IER, I2C_INT_DATA | I2C_INT_ADDR | I2C_INT_STOP);

	if (bootverbose)
		device_printf(self, "Revision: %02X\n", kiic_readreg(sc, REV));

	/* Add the IIC bus layer */
	sc->sc_iicbus = device_add_child(self, "iicbus", -1);

	return (bus_generic_attach(self));
}