Esempio n. 1
0
static int
i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr)
{
	struct i2c_softc *sc;

	sc = device_get_softc(dev);

	vf_i2c_dbg(sc, "i2c reset\n");

	switch (speed) {
	case IIC_FAST:
	case IIC_SLOW:
	case IIC_UNKNOWN:
	case IIC_FASTEST:
	default:
		break;
	}

	mtx_lock(&sc->mutex);
	WRITE1(sc, I2C_IBCR, IBCR_MDIS);

	DELAY(1000);

	WRITE1(sc, I2C_IBFD, 20);
	WRITE1(sc, I2C_IBCR, 0x0); /* Enable i2c */

	DELAY(1000);

	mtx_unlock(&sc->mutex);

	return (IIC_NOERR);
}
static void
auacer_halt(struct auacer_softc *sc, struct auacer_chan *chan)
{
	uint32_t val;
	uint8_t port;
	uint32_t slot;

	port = chan->port;
	DPRINTF(ALI_DEBUG_API, ("auacer_halt: port=0x%x\n", port));
	chan->intr = 0;

	slot = ALI_PORT2SLOT(port);

	val = READ4(sc, ALI_DMACR);
	val |= 1 << (slot+16); /* pause */
	val &= ~(1 << slot); /* no start */
	WRITE4(sc, ALI_DMACR, val);
	WRITE1(sc, port + ALI_OFF_CR, 0);
	while (READ1(sc, port + ALI_OFF_CR))
		;
	/* reset whole DMA things */
	WRITE1(sc, port + ALI_OFF_CR, ALI_CR_RR);
	/* clear interrupts */
	WRITE1(sc, port + ALI_OFF_SR, READ1(sc, port+ALI_OFF_SR) | ALI_SR_W1TC);
	WRITE4(sc, ALI_INTERRUPTSR, ALI_PORT2INTR(port));
}
static void
auacer_setup_chan(struct auacer_softc *sc, struct auacer_chan *chan,
		  uint32_t start, uint32_t size, uint32_t blksize,
		  void (*intr)(void *), void *arg)
{
	uint32_t port, slot;
	uint32_t offs, val;

	chan->start = start;
	chan->ptr = 0;
	chan->p = chan->start;
	chan->end = chan->start + size;
	chan->blksize = blksize;
	chan->ack = 0;
	chan->intr = intr;
	chan->arg = arg;

	auacer_add_entry(chan);
	auacer_add_entry(chan);

	port = chan->port;
	slot = ALI_PORT2SLOT(port);

	WRITE1(sc, port + ALI_OFF_CIV, 0);
	WRITE1(sc, port + ALI_OFF_LVI, (chan->ptr - 1) & ALI_LVI_MASK);
	offs = (char *)chan->dmalist - (char *)sc->sc_cdata;
	WRITE4(sc, port + ALI_OFF_BDBAR, sc->sc_cddma + offs);
	WRITE1(sc, port + ALI_OFF_CR,
	       ALI_CR_IOCE | ALI_CR_FEIE | ALI_CR_LVBIE | ALI_CR_RPBM);
	val = READ4(sc, ALI_DMACR);
	val &= ~(1 << (slot+16)); /* no pause */
	val |= 1 << slot;	/* start */
	WRITE4(sc, ALI_DMACR, val);
}
Esempio n. 4
0
static int
i2c_read(device_t dev, char *buf, int len,
    int *read, int last, int delay)
{
	struct i2c_softc *sc;
	int error;
	int reg;
	uint8_t d;

	sc = device_get_softc(dev);

	DPRINTF("i2c read\n");

	reg = (RXTX_EN);
	reg |= (I2CMODE_MR << I2CMODE_S);
	reg |= I2C_START_STOP;
	WRITE1(sc, I2CSTAT, reg);

	*read = 0;
	mtx_lock(&sc->mutex);

	/* dummy read */
	clear_ipend(sc);
	error = wait_for_iif(sc);
	if (error) {
		DPRINTF("cant i2c read: iif error\n");
		mtx_unlock(&sc->mutex);
		return (error);
	}
	READ1(sc, I2CDS);

	DPRINTF("Read ");
	while (*read < len) {

		/* Do not ack last read */
		if (*read == (len - 1)) {
			reg = READ1(sc, I2CCON);
			reg &= ~(ACKGEN);
			WRITE1(sc, I2CCON, reg);
		}

		clear_ipend(sc);

		error = wait_for_iif(sc);
		if (error) {
			DPRINTF("cant i2c read: iif error\n");
			mtx_unlock(&sc->mutex);
			return (error);
		}

		d = READ1(sc, I2CDS);
		DPRINTF("0x%02x ", d);
		*buf++ = d;
		(*read)++;
	}
	DPRINTF("\n");

	mtx_unlock(&sc->mutex);
	return (IIC_NOERR);
}
Esempio n. 5
0
static int
i2c_stop(device_t dev)
{
	struct i2c_softc *sc;

	sc = device_get_softc(dev);

	vf_i2c_dbg(sc, "i2c stop\n");

	mtx_lock(&sc->mutex);

	WRITE1(sc, I2C_IBCR, IBCR_NOACK | IBCR_IBIE);

	DELAY(100);

	/* Reset controller if bus still busy after STOP */
	if (wait_for_nibb(sc) == IIC_ETIMEOUT) {
		WRITE1(sc, I2C_IBCR, IBCR_MDIS);
		DELAY(1000);
		WRITE1(sc, I2C_IBCR, IBCR_NOACK);
	}
	mtx_unlock(&sc->mutex);

	return (IIC_NOERR);
}
Esempio n. 6
0
static int
i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay)
{
	struct i2c_softc *sc;
	int error;

	sc = device_get_softc(dev);

	vf_i2c_dbg(sc, "i2c read\n");

	*read = 0;

	mtx_lock(&sc->mutex);

	if (len) {
		if (len == 1)
			WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL |	\
			    IBCR_NOACK);
		else
			WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL);

		/* dummy read */
		READ1(sc, I2C_IBDR);
		DELAY(1000);
	}

	while (*read < len) {
		error = wait_for_icf(sc);
		if (error) {
			mtx_unlock(&sc->mutex);
			return (error);
		}

		if ((*read == len - 2) && last) {
			/* NO ACK on last byte */
			WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL |	\
			    IBCR_NOACK);
		}

		if ((*read == len - 1) && last) {
			/* Transfer done, remove master bit */
			WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_NOACK);
		}

		*buf++ = READ1(sc, I2C_IBDR);
		(*read)++;
	}
	mtx_unlock(&sc->mutex);

	return (IIC_NOERR);
}
Esempio n. 7
0
static int
i2c_stop(device_t dev)
{
	struct i2c_softc *sc;
	int reg;
	int error;

	sc = device_get_softc(dev);

	DPRINTF("i2c stop\n");

	mtx_lock(&sc->mutex);

	reg = READ1(sc, I2CSTAT);
	int mode = (reg >> I2CMODE_S) & I2CMODE_M;

	reg = (RXTX_EN);
	reg |= (mode << I2CMODE_S);
	WRITE1(sc, I2CSTAT, reg);

	clear_ipend(sc);

	error = wait_for_nibb(sc);
	if (error) {
		DPRINTF("cant i2c stop: nibb error\n");
		return (error);
	}

	mtx_unlock(&sc->mutex);
	return (IIC_NOERR);
}
Esempio n. 8
0
static int
i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout)
{
	struct i2c_softc *sc;
	int error;

	sc = device_get_softc(dev);

	vf_i2c_dbg(sc, "i2c write\n");

	*sent = 0;

	mtx_lock(&sc->mutex);
	while (*sent < len) {

		WRITE1(sc, I2C_IBDR, *buf++);

		error = wait_for_iif(sc);
		if (error) {
			mtx_unlock(&sc->mutex);
			return (error);
		}

		(*sent)++;
	}
	mtx_unlock(&sc->mutex);

	return (IIC_NOERR);
}
Esempio n. 9
0
static int
i2c_attach(device_t dev)
{
	struct i2c_softc *sc;

	sc = device_get_softc(dev);
	sc->dev = dev;

	mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF);

	if (bus_alloc_resources(dev, i2c_spec, sc->res)) {
		device_printf(dev, "could not allocate resources\n");
		return (ENXIO);
	}

	/* Memory interface */
	sc->bst = rman_get_bustag(sc->res[0]);
	sc->bsh = rman_get_bushandle(sc->res[0]);

	WRITE1(sc, I2C_IBIC, IBIC_BIIE);

	sc->iicbus = device_add_child(dev, "iicbus", -1);
	if (sc->iicbus == NULL) {
		device_printf(dev, "could not add iicbus child");
		mtx_destroy(&sc->mutex);
		return (ENXIO);
	}

	bus_generic_attach(dev);

	return (0);
}
Esempio n. 10
0
static int
i2c_start(device_t dev, u_char slave, int timeout)
{
	struct i2c_softc *sc;
	int error;
	int reg;

	sc = device_get_softc(dev);

	vf_i2c_dbg(sc, "i2c start\n");

	mtx_lock(&sc->mutex);

	WRITE1(sc, I2C_IBAD, slave);

	if (READ1(sc, I2C_IBSR) & IBSR_IBB) {
		mtx_unlock(&sc->mutex);
		vf_i2c_dbg(sc, "cant i2c start: IIC_EBUSBSY\n");
		return (IIC_EBUSBSY);
	}

	/* Set start condition */
	reg = (IBCR_MSSL | IBCR_NOACK | IBCR_IBIE);
	WRITE1(sc, I2C_IBCR, reg);

	DELAY(100);

	reg |= (IBCR_TXRX);
	WRITE1(sc, I2C_IBCR, reg);

	/* Write target address - LSB is R/W bit */
	WRITE1(sc, I2C_IBDR, slave);

	error = wait_for_iif(sc);

	mtx_unlock(&sc->mutex);
	if (error) {
		vf_i2c_dbg(sc, "cant i2c start: iif error\n");
		return (error);
	}

	return (IIC_NOERR);
}
Esempio n. 11
0
static int
clear_ipend(struct i2c_softc *sc)
{
	int reg;

	reg = READ1(sc, I2CCON);
	reg &= ~(IPEND);
	WRITE1(sc, I2CCON, reg);

	return (0);
}
Esempio n. 12
0
static int
i2c_repeated_start(device_t dev, u_char slave, int timeout)
{
	struct i2c_softc *sc;
	int error;
	int reg;

	sc = device_get_softc(dev);

	vf_i2c_dbg(sc, "i2c repeated start\n");

	mtx_lock(&sc->mutex);

	WRITE1(sc, I2C_IBAD, slave);

	if ((READ1(sc, I2C_IBSR) & IBSR_IBB) == 0) {
		mtx_unlock(&sc->mutex);
		return (IIC_EBUSBSY);
	}

	/* Set repeated start condition */
	DELAY(10);

	reg = READ1(sc, I2C_IBCR);
	reg |= (IBCR_RSTA | IBCR_IBIE);
	WRITE1(sc, I2C_IBCR, reg);

	DELAY(10);

	/* Write target address - LSB is R/W bit */
	WRITE1(sc, I2C_IBDR, slave);

	error = wait_for_iif(sc);

	mtx_unlock(&sc->mutex);

	if (error)
		return (error);

	return (IIC_NOERR);
}
Esempio n. 13
0
static int
i2c_attach(device_t dev)
{
	struct i2c_softc *sc;
	int reg;

	sc = device_get_softc(dev);
	sc->dev = dev;

	mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF);

	if (bus_alloc_resources(dev, i2c_spec, sc->res)) {
		device_printf(dev, "could not allocate resources\n");
		return (ENXIO);
	}

	/* Memory interface */
	sc->bst = rman_get_bustag(sc->res[0]);
	sc->bsh = rman_get_bushandle(sc->res[0]);

	sc->iicbus = device_add_child(dev, "iicbus", -1);
	if (sc->iicbus == NULL) {
		device_printf(dev, "could not add iicbus child");
		mtx_destroy(&sc->mutex);
		return (ENXIO);
	}

	WRITE1(sc, I2CSTAT, 0);
	WRITE1(sc, I2CADD, 0x00);

	/* Mode */
	reg = (RXTX_EN);
        reg |= (I2CMODE_MT << I2CMODE_S);
	WRITE1(sc, I2CSTAT, reg);

	bus_generic_attach(dev);

	return (0);
}
Esempio n. 14
0
/* Wait for transfer interrupt flag */
static int
wait_for_iif(struct i2c_softc *sc)
{
	int retry;

	retry = 1000;
	while (retry --) {
		if (READ1(sc, I2C_IBSR) & IBSR_IBIF) {
			WRITE1(sc, I2C_IBSR, IBSR_IBIF);
			return (IIC_NOERR);
		}
		DELAY(10);
	}

	return (IIC_ETIMEOUT);
}
Esempio n. 15
0
static void
edma_err_intr(void *arg)
{
	struct edma_softc *sc;
	int reg;

	sc = arg;

	reg = READ4(sc, DMA_ERR);

#if 0
	device_printf(sc->dev, "DMA_ERR 0x%08x, ES 0x%08x\n",
	    reg, READ4(sc, DMA_ES));
#endif

	WRITE1(sc, DMA_CERR, CERR_CAEI);
}
Esempio n. 16
0
static int
i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout)
{
	struct i2c_softc *sc;
	int error;

	sc = device_get_softc(dev);

	DPRINTF("i2c write\n");

	*sent = 0;

	mtx_lock(&sc->mutex);

	DPRINTF("writing ");
	while (*sent < len) {
		uint8_t d = *buf++;
		DPRINTF("0x%02x ", d);

		WRITE1(sc, I2CDS, d);
		DELAY(50);

		clear_ipend(sc);

		error = wait_for_iif(sc);
		if (error) {
			DPRINTF("cant i2c write: iif error\n");
			mtx_unlock(&sc->mutex);
			return (error);
		}

		if (!is_ack(sc)) {
			DPRINTF("cant i2c write: no ack\n");
			mtx_unlock(&sc->mutex);
			return (IIC_ENOACK);
		}

		(*sent)++;
	}
	DPRINTF("\n");

	mtx_unlock(&sc->mutex);
	return (IIC_NOERR);
}
Esempio n. 17
0
static void
auacer_upd_chan(struct auacer_softc *sc, struct auacer_chan *chan)
{
	uint32_t sts;
	uint32_t civ;

	sts = READ2(sc, chan->port + ALI_OFF_SR);
	/* intr ack */
	WRITE2(sc, chan->port + ALI_OFF_SR, sts & ALI_SR_W1TC);
	WRITE4(sc, ALI_INTERRUPTSR, ALI_PORT2INTR(chan->port));

	DPRINTF(ALI_DEBUG_INTR, ("auacer_upd_chan: sts=0x%x\n", sts));

	if (sts & ALI_SR_DMA_INT_FIFO) {
		printf("%s: fifo underrun # %u\n",
		       device_xname(&sc->sc_dev), ++chan->fifoe);
	}

	civ = READ1(sc, chan->port + ALI_OFF_CIV);

	DPRINTF(ALI_DEBUG_INTR,("auacer_intr: civ=%u ptr=%u\n",civ,chan->ptr));

	/* XXX */
	while (chan->ptr != civ) {
		auacer_add_entry(chan);
	}

	WRITE1(sc, chan->port + ALI_OFF_LVI, (chan->ptr - 1) & ALI_LVI_MASK);

	while (chan->ack != civ) {
		if (chan->intr) {
			DPRINTF(ALI_DEBUG_INTR,("auacer_upd_chan: callback\n"));
			chan->intr(chan->arg);
		}
		chan->ack++;
		if (chan->ack >= ALI_DMALIST_MAX)
			chan->ack = 0;
	}
}
Esempio n. 18
0
static void
edma_transfer_complete_intr(void *arg)
{
	struct edma_channel *ch;
	struct edma_softc *sc;
	int interrupts;
	int i;

	sc = arg;

	interrupts = READ4(sc, DMA_INT);
	WRITE1(sc, DMA_CINT, CINT_CAIR);

	for (i = 0; i < EDMA_NUM_CHANNELS; i++) {
		if (interrupts & (0x1 << i)) {
			ch = &edma_map[i];
			if (ch->enabled == 1) {
				if (ch->ih != NULL) {
					ch->ih(ch->ih_user, i);
				}
			}
		}
	}
}
Esempio n. 19
0
void
fbGlyph24(FbBits * dstBits,
          FbStride dstStride,
          int dstBpp, FbStip * stipple, FbBits fg, int x, int height)
{
    int lshift;

    FbStip bits;

    CARD8 *dstLine;

    CARD8 *dst;

    FbStip f0, f1, f2;

    int n;

    int shift;

    f0 = fg;
    f1 = FbRot24(f0, 16);
    f2 = FbRot24(f0, 8);

    dstLine = (CARD8 *) dstBits;
    dstLine += (x & ~3) * 3;
    dstStride *= (sizeof(FbBits) / sizeof(CARD8));
    shift = x & 3;
    lshift = 4 - shift;
    while (height--) {
        bits = *stipple++;
        n = lshift;
        dst = dstLine;
        while (bits) {
            switch (FbStipMoveLsb(FbLeftStipBits(bits, n), 4, n)) {
            case CASE(0, 0, 0, 0):
                break;
            case CASE(1, 0, 0, 0):
                WRITE2(dst, 0, _AB);
                WRITE1(dst, 2, _C);
                break;
            case CASE(0, 1, 0, 0):
                WRITE1(dst, 3, _A);
                WRITE2(dst, 4, _BC);
                break;
            case CASE(1, 1, 0, 0):
                WRITE4(dst, 0, _ABCA);
                WRITE2(dst, 4, _BC);
                break;
            case CASE(0, 0, 1, 0):
                WRITE2(dst, 6, _AB);
                WRITE1(dst, 8, _C);
                break;
            case CASE(1, 0, 1, 0):
                WRITE2(dst, 0, _AB);
                WRITE1(dst, 2, _C);

                WRITE2(dst, 6, _AB);
                WRITE1(dst, 8, _C);
                break;
            case CASE(0, 1, 1, 0):
                WRITE1(dst, 3, _A);
                WRITE4(dst, 4, _BCAB);
                WRITE1(dst, 8, _C);
                break;
            case CASE(1, 1, 1, 0):
                WRITE8(dst);
                WRITE1(dst, 8, _C);
                break;
            case CASE(0, 0, 0, 1):
                WRITE1(dst, 9, _A);
                WRITE2(dst, 10, _BC);
                break;
            case CASE(1, 0, 0, 1):
                WRITE2(dst, 0, _AB);
                WRITE1(dst, 2, _C);

                WRITE1(dst, 9, _A);
                WRITE2(dst, 10, _BC);
                break;
            case CASE(0, 1, 0, 1):
                WRITE1(dst, 3, _A);
                WRITE2(dst, 4, _BC);

                WRITE1(dst, 9, _A);
                WRITE2(dst, 10, _BC);
                break;
            case CASE(1, 1, 0, 1):
                WRITE4(dst, 0, _ABCA);
                WRITE2(dst, 4, _BC);

                WRITE1(dst, 9, _A);
                WRITE2(dst, 10, _BC);
                break;
            case CASE(0, 0, 1, 1):
                WRITE2(dst, 6, _AB);
                WRITE4(dst, 8, _CABC);
                break;
            case CASE(1, 0, 1, 1):
                WRITE2(dst, 0, _AB);
                WRITE1(dst, 2, _C);

                WRITE2(dst, 6, _AB);
                WRITE4(dst, 8, _CABC);
                break;
            case CASE(0, 1, 1, 1):
                WRITE1(dst, 3, _A);
                WRITE4(dst, 4, _BCAB);
                WRITE4(dst, 8, _CABC);
                break;
            case CASE(1, 1, 1, 1):
                WRITE8(dst);
                WRITE4(dst, 8, _CABC);
                break;
            }
            bits = FbStipLeft(bits, n);
            n = 4;
            dst += 12;
        }
        dstLine += dstStride;
    }
}
Esempio n. 20
0
static int
i2c_start(device_t dev, u_char slave, int timeout)
{
	struct i2c_softc *sc;
	int error;
	int reg;

	sc = device_get_softc(dev);

	DPRINTF("i2c start\n");

	mtx_lock(&sc->mutex);

#if 0
	DPRINTF("I2CCON == 0x%08x\n", READ1(sc, I2CCON));
	DPRINTF("I2CSTAT == 0x%08x\n", READ1(sc, I2CSTAT));
#endif

	if (slave & 1) {
		slave &= ~(1);
		slave <<= 1;
		slave |= 1;
	} else {
		slave <<= 1;
	}

	error = wait_for_nibb(sc);
	if (error) {
		mtx_unlock(&sc->mutex);
		DPRINTF("cant i2c start: IIC_EBUSERR\n");
		return (IIC_EBUSERR);
	}

	reg = READ1(sc, I2CCON);
	reg |= (IRQ_EN | ACKGEN);
	WRITE1(sc, I2CCON, reg);

	WRITE1(sc, I2CDS, slave);
	DELAY(50);

	reg = (RXTX_EN);
	reg |= I2C_START_STOP;
	reg |= (I2CMODE_MT << I2CMODE_S);
	WRITE1(sc, I2CSTAT, reg);

	error = wait_for_iif(sc);
	if (error) {
		DPRINTF("cant i2c start: iif error\n");

		mtx_unlock(&sc->mutex);
		return (error);
	}

	if (!is_ack(sc)) {
		DPRINTF("cant i2c start: no ack\n");

		mtx_unlock(&sc->mutex);
		return (IIC_ENOACK);
	}

	mtx_unlock(&sc->mutex);
	return (IIC_NOERR);
}