Example #1
0
int
kiic_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr,
    const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags)
{
	struct kiic_bus *bus = cookie;
	u_int mode = I2C_STDSUBMODE;
	u_int8_t cmd = 0;

	if (!I2C_OP_STOP_P(op) || cmdlen > 1)
		return (EINVAL);

	if (cmdlen == 0)
		mode = I2C_STDMODE;
	else if (I2C_OP_READ_P(op))
		mode = I2C_COMBMODE;

	if (cmdlen > 0)
		cmd = *(u_int8_t *)cmdbuf;

	kiic_setmode(bus->sc, mode, bus->reg || addr & 0x80);
	addr &= 0x7f;

	if (I2C_OP_READ_P(op)) {
		if (kiic_read(bus->sc, (addr << 1), cmd, buf, len) != 0)
			return (EIO);
	} else {
		if (kiic_write(bus->sc, (addr << 1), cmd, buf, len) != 0)
			return (EIO);
	}
	return (0);
}
Example #2
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);
}
Example #3
0
static int
kiic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
{
	struct kiic_softc *sc;
	int i, x, timo, err;
	uint16_t addr;
	uint8_t subaddr;

	sc = device_get_softc(dev);
	timo = 100;
	subaddr = 0;

	mtx_lock(&sc->sc_mutex);

	if (sc->sc_flags & I2C_BUSY)
		mtx_sleep(dev, &sc->sc_mutex, 0, "kiic", timo);

	if (sc->sc_flags & I2C_BUSY) {
		mtx_unlock(&sc->sc_mutex);
		return (ETIMEDOUT);
	}
		
	sc->sc_flags = I2C_BUSY;

	/* Clear pending interrupts, and reset controller */
	kiic_writereg(sc, ISR, kiic_readreg(sc, ISR));
	kiic_writereg(sc, STATUS, 0);

	for (i = 0; i < nmsgs; i++) {
		if (msgs[i].flags & IIC_M_NOSTOP) {
			if (msgs[i+1].flags & IIC_M_RD)
				kiic_setmode(sc, I2C_COMBMODE);
			else
				kiic_setmode(sc, I2C_STDSUBMODE);
			KASSERT(msgs[i].len == 1, ("oversize I2C message"));
			subaddr = msgs[i].buf[0];
			i++;
		} else {
			kiic_setmode(sc, I2C_STDMODE);
		}

		sc->sc_data = msgs[i].buf;
		sc->sc_resid = msgs[i].len;
		sc->sc_flags = I2C_BUSY;
		addr = msgs[i].slave;
		timo = 1000 + sc->sc_resid * 200;
		timo += 100000;

		if (msgs[i].flags & IIC_M_RD) {
			sc->sc_flags |= I2C_READING;
			addr |= 1;
		}

		addr |= sc->sc_i2c_base;

		kiic_setport(sc, (addr & 0x100) >> 8);
		kiic_writereg(sc, ADDR, addr & 0xff);
		kiic_writereg(sc, SUBADDR, subaddr);

		x = kiic_readreg(sc, CONTROL) | I2C_CT_ADDR;
		kiic_writereg(sc, CONTROL, x);

		err = mtx_sleep(dev, &sc->sc_mutex, 0, "kiic", timo);
		
		msgs[i].len -= sc->sc_resid;

		if ((sc->sc_flags & I2C_ERROR) || err == EWOULDBLOCK) {
			device_printf(sc->sc_dev, "I2C error\n");
			sc->sc_flags = 0;
			mtx_unlock(&sc->sc_mutex);
			return (EIO);
		}
	}

	sc->sc_flags = 0;

	mtx_unlock(&sc->sc_mutex);

	return (0);
}
Example #4
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));
}