[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

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