[BACK]Return to pxa2x0_i2c.c CVS log [TXT][DIR] Up to [local] / sys / arch / arm / xscale

Annotation of sys/arch/arm/xscale/pxa2x0_i2c.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: pxa2x0_i2c.c,v 1.2 2005/05/26 03:52:07 pascoe Exp $   */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2005 Christopher Pascoe <pascoe@openbsd.org>
        !             5:  *
        !             6:  * Permission to use, copy, modify, and distribute this software for any
        !             7:  * purpose with or without fee is hereby granted, provided that the above
        !             8:  * copyright notice and this permission notice appear in all copies.
        !             9:  *
        !            10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            17:  */
        !            18:
        !            19: #include <sys/param.h>
        !            20: #include <sys/systm.h>
        !            21:
        !            22: #include <arm/xscale/pxa2x0reg.h>
        !            23: #include <arm/xscale/pxa2x0var.h>
        !            24: #include <arm/xscale/pxa2x0_i2c.h>
        !            25: #include <arm/xscale/pxa2x0_gpio.h>
        !            26:
        !            27: #define I2C_RETRY_COUNT        10
        !            28:
        !            29: int
        !            30: pxa2x0_i2c_attach_sub(struct pxa2x0_i2c_softc *sc)
        !            31: {
        !            32:        if (bus_space_map(sc->sc_iot, PXA2X0_I2C_BASE,
        !            33:            PXA2X0_I2C_SIZE, 0, &sc->sc_ioh)) {
        !            34:                sc->sc_size = 0;
        !            35:                return EIO;
        !            36:        }
        !            37:        bus_space_barrier(sc->sc_iot, sc->sc_ioh, 0, sc->sc_size,
        !            38:            BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
        !            39:
        !            40:        /*
        !            41:         * Configure the alternate functions.  The _IN is arbitrary, as the
        !            42:         * direction is managed by the I2C unit when comms are in progress.
        !            43:         */
        !            44:        pxa2x0_gpio_set_function(117, GPIO_ALT_FN_1_IN);        /* SCL */
        !            45:        pxa2x0_gpio_set_function(118, GPIO_ALT_FN_1_IN);        /* SDA */
        !            46:
        !            47:        pxa2x0_i2c_init(sc);
        !            48:
        !            49:        return 0;
        !            50: }
        !            51:
        !            52: int
        !            53: pxa2x0_i2c_detach_sub(struct pxa2x0_i2c_softc *sc)
        !            54: {
        !            55:        if (sc->sc_size) {
        !            56:                bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
        !            57:                sc->sc_size = 0;
        !            58:        }
        !            59:        pxa2x0_clkman_config(CKEN_I2C, 0);
        !            60:
        !            61:        return 0;
        !            62: }
        !            63:
        !            64: void
        !            65: pxa2x0_i2c_init(struct pxa2x0_i2c_softc *sc)
        !            66: {
        !            67:        pxa2x0_i2c_open(sc);
        !            68:        pxa2x0_i2c_close(sc);
        !            69: }
        !            70:
        !            71: void
        !            72: pxa2x0_i2c_open(struct pxa2x0_i2c_softc *sc)
        !            73: {
        !            74:        /* Enable the clock to the standard I2C unit. */
        !            75:        pxa2x0_clkman_config(CKEN_I2C, 1);
        !            76: }
        !            77:
        !            78: void
        !            79: pxa2x0_i2c_close(struct pxa2x0_i2c_softc *sc)
        !            80: {
        !            81:        /* Reset and disable the standard I2C unit. */
        !            82:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, I2C_ICR, ICR_UR);
        !            83:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, I2C_ISAR, 0);
        !            84:        delay(1);
        !            85:        pxa2x0_clkman_config(CKEN_I2C, 0);
        !            86: }
        !            87:
        !            88: int
        !            89: pxa2x0_i2c_read(struct pxa2x0_i2c_softc *sc, u_char slave, u_char *valuep)
        !            90: {
        !            91:        u_int32_t rv;
        !            92:        int timeout;
        !            93:        int tries = I2C_RETRY_COUNT;
        !            94:        bus_space_tag_t iot = sc->sc_iot;
        !            95:        bus_space_handle_t ioh = sc->sc_ioh;
        !            96:
        !            97: retry:
        !            98:        bus_space_write_4(iot, ioh, I2C_ICR, ICR_UR);
        !            99:        bus_space_write_4(iot, ioh, I2C_ISAR, 0x00);
        !           100:        bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE | ISR_IRF);
        !           101:        delay(1);
        !           102:        bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE);
        !           103:
        !           104:        /* Write slave device address. */
        !           105:        bus_space_write_4(iot, ioh, I2C_IDBR, (slave<<1) | 0x1);
        !           106:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           107:        bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_START);
        !           108:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           109:        bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP);
        !           110:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           111:        bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB);
        !           112:
        !           113:        timeout = 10000;
        !           114:        while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) {
        !           115:                if (timeout-- == 0)
        !           116:                        goto err;
        !           117:                delay(1);
        !           118:        }
        !           119:
        !           120:        bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
        !           121:
        !           122:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           123:        bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_START);
        !           124:
        !           125:        /* Read data value. */
        !           126:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           127:        bus_space_write_4(iot, ioh, I2C_ICR, rv |
        !           128:            (ICR_STOP | ICR_ACKNAK));
        !           129:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           130:        bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB);
        !           131:
        !           132:        timeout = 10000;
        !           133:        while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_IRF) == 0) {
        !           134:                if (timeout-- == 0)
        !           135:                        goto err;
        !           136:                delay(1);
        !           137:        }
        !           138:
        !           139:        bus_space_write_4(iot, ioh, I2C_ISR, ISR_IRF);
        !           140:
        !           141:        rv = bus_space_read_4(iot, ioh, I2C_IDBR);
        !           142:        *valuep = (u_char)rv;
        !           143:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           144:        bus_space_write_4(iot, ioh, I2C_ICR, rv &
        !           145:            ~(ICR_STOP | ICR_ACKNAK));
        !           146:
        !           147:        return (0);
        !           148: err:
        !           149:        if (tries-- >= 0)
        !           150:                goto retry;
        !           151:
        !           152:        bus_space_write_4(iot, ioh, I2C_ICR, ICR_UR);
        !           153:        bus_space_write_4(iot, ioh, I2C_ISAR, 0x00);
        !           154:        bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE | ISR_IRF);
        !           155:        bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE);
        !           156:
        !           157:        return (-EIO);
        !           158: }
        !           159:
        !           160: int
        !           161: pxa2x0_i2c_write(struct pxa2x0_i2c_softc *sc, u_char slave, u_char value)
        !           162: {
        !           163:        u_int32_t rv;
        !           164:        int timeout;
        !           165:        int tries = I2C_RETRY_COUNT;
        !           166:        bus_space_tag_t iot = sc->sc_iot;
        !           167:        bus_space_handle_t ioh = sc->sc_ioh;
        !           168:
        !           169: retry:
        !           170:        bus_space_write_4(iot, ioh, I2C_ICR, ICR_UR);
        !           171:        bus_space_write_4(iot, ioh, I2C_ISAR, 0x00);
        !           172:        bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
        !           173:        delay(1);
        !           174:        bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE);
        !           175:
        !           176:        /* Write slave device address. */
        !           177:        bus_space_write_4(iot, ioh, I2C_IDBR, (slave<<1));
        !           178:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           179:        bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_START);
        !           180:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           181:        bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP);
        !           182:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           183:        bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB);
        !           184:
        !           185:        timeout = 10000;
        !           186:        while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) {
        !           187:                if (timeout-- == 0)
        !           188:                        goto err;
        !           189:                delay(1);
        !           190:        }
        !           191:        if ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ACKNAK) != 0)
        !           192:                goto err;
        !           193:
        !           194:        bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
        !           195:
        !           196:        /* Write data. */
        !           197:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           198:        bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_START);
        !           199:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           200:        bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_STOP);
        !           201:        bus_space_write_4(iot, ioh, I2C_IDBR, value);
        !           202:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           203:        bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB);
        !           204:
        !           205:        timeout = 10000;
        !           206:        while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) {
        !           207:                if (timeout-- == 0)
        !           208:                        goto err;
        !           209:                delay(1);
        !           210:        }
        !           211:        if ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ACKNAK) != 0)
        !           212:                goto err;
        !           213:
        !           214:        bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
        !           215:
        !           216:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           217:        bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP);
        !           218:
        !           219:        return (0);
        !           220: err:
        !           221:        if (tries-- >= 0)
        !           222:                goto retry;
        !           223:
        !           224:        bus_space_write_4(iot, ioh, I2C_ICR, ICR_UR);
        !           225:        bus_space_write_4(iot, ioh, I2C_ISAR, 0x00);
        !           226:        bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
        !           227:        bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE);
        !           228:
        !           229:        return (-EIO);
        !           230: }
        !           231:
        !           232: int
        !           233: pxa2x0_i2c_write_2(struct pxa2x0_i2c_softc *sc, u_char slave, u_short value)
        !           234: {
        !           235:        u_int32_t rv;
        !           236:        int timeout;
        !           237:        int tries = I2C_RETRY_COUNT;
        !           238:        bus_space_tag_t iot = sc->sc_iot;
        !           239:        bus_space_handle_t ioh = sc->sc_ioh;
        !           240:
        !           241: retry:
        !           242:        bus_space_write_4(iot, ioh, I2C_ICR, ICR_UR);
        !           243:        bus_space_write_4(iot, ioh, I2C_ISAR, 0x00);
        !           244:        bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
        !           245:        delay(1);
        !           246:        bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE);
        !           247:
        !           248:        /* Write slave device address. */
        !           249:        bus_space_write_4(iot, ioh, I2C_IDBR, (slave<<1));
        !           250:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           251:        bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_START);
        !           252:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           253:        bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP);
        !           254:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           255:        bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB);
        !           256:
        !           257:        timeout = 10000;
        !           258:        while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) {
        !           259:                if (timeout-- == 0)
        !           260:                        goto err;
        !           261:                delay(1);
        !           262:        }
        !           263:        if ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ACKNAK) != 0)
        !           264:                goto err;
        !           265:
        !           266:        bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
        !           267:
        !           268:        /* Write upper 8 bits of data. */
        !           269:        bus_space_write_4(iot, ioh, I2C_IDBR, (value >> 8) & 0xff);
        !           270:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           271:        bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_START);
        !           272:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           273:        bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP);
        !           274:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           275:        bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB);
        !           276:
        !           277:        timeout = 10000;
        !           278:        while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) {
        !           279:                if (timeout-- == 0)
        !           280:                        goto err;
        !           281:                delay(1);
        !           282:        }
        !           283:        if ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ACKNAK) != 0)
        !           284:                goto err;
        !           285:
        !           286:        bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
        !           287:
        !           288:        /* Write lower 8 bits of data. */
        !           289:        bus_space_write_4(iot, ioh, I2C_IDBR, value & 0xff);
        !           290:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           291:        bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_START);
        !           292:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           293:        bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_STOP);
        !           294:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           295:        bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB);
        !           296:
        !           297:        timeout = 10000;
        !           298:        while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) {
        !           299:                if (timeout-- == 0)
        !           300:                        goto err;
        !           301:                delay(1);
        !           302:        }
        !           303:        if ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ACKNAK) != 0)
        !           304:                goto err;
        !           305:
        !           306:        bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
        !           307:
        !           308:        rv = bus_space_read_4(iot, ioh, I2C_ICR);
        !           309:        bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP);
        !           310:
        !           311:        return (0);
        !           312: err:
        !           313:        if (tries-- >= 0)
        !           314:                goto retry;
        !           315:
        !           316:        bus_space_write_4(iot, ioh, I2C_ICR, ICR_UR);
        !           317:        bus_space_write_4(iot, ioh, I2C_ISAR, 0x00);
        !           318:        bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
        !           319:        bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE);
        !           320:
        !           321:        return (-EIO);
        !           322: }

CVSweb