[BACK]Return to piic.c CVS log [TXT][DIR] Up to [local] / sys / arch / macppc / dev

Annotation of sys/arch/macppc/dev/piic.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: piic.c,v 1.2 2007/05/20 23:38:52 thib Exp $   */
                      2:
                      3: /*
                      4:  * Copyright (c) 2005 Mark Kettenis
                      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: #include <sys/device.h>
                     22: #include <sys/rwlock.h>
                     23: #include <sys/proc.h>
                     24:
                     25: #include <machine/autoconf.h>
                     26:
                     27: #include <dev/i2c/i2cvar.h>
                     28:
                     29: #include <arch/macppc/dev/maci2cvar.h>
                     30: #include <arch/macppc/dev/pm_direct.h>
                     31:
                     32: struct piic_softc {
                     33:        struct device   sc_dev;
                     34:
                     35:        struct rwlock   sc_buslock;
                     36:        struct i2c_controller sc_i2c_tag;
                     37: };
                     38:
                     39: int     piic_match(struct device *, void *, void *);
                     40: void    piic_attach(struct device *, struct device *, void *);
                     41:
                     42: struct cfattach piic_ca = {
                     43:        sizeof(struct piic_softc), piic_match, piic_attach
                     44: };
                     45:
                     46: struct cfdriver piic_cd = {
                     47:         NULL, "piic", DV_DULL,
                     48: };
                     49:
                     50: int    piic_i2c_acquire_bus(void *, int);
                     51: void   piic_i2c_release_bus(void *, int);
                     52: int    piic_i2c_exec(void *, i2c_op_t, i2c_addr_t,
                     53:            const void *, size_t, void *buf, size_t, int);
                     54:
                     55: int
                     56: piic_match(struct device *parent, void *cf, void *aux)
                     57: {
                     58:        return (1);
                     59: }
                     60:
                     61: void
                     62: piic_attach(struct device *parent, struct device *self, void *aux)
                     63: {
                     64:        struct piic_softc *sc = (struct piic_softc *)self;
                     65:        struct confargs *ca = aux;
                     66:        struct i2cbus_attach_args iba;
                     67:
                     68:        printf("\n");
                     69:
                     70:        rw_init(&sc->sc_buslock, sc->sc_dev.dv_xname);
                     71:
                     72:        sc->sc_i2c_tag.ic_cookie = sc;
                     73:        sc->sc_i2c_tag.ic_acquire_bus = piic_i2c_acquire_bus;
                     74:        sc->sc_i2c_tag.ic_release_bus = piic_i2c_release_bus;
                     75:        sc->sc_i2c_tag.ic_exec = piic_i2c_exec;
                     76:
                     77:        bzero(&iba, sizeof iba);
                     78:        iba.iba_name = "iic";
                     79:        iba.iba_tag = &sc->sc_i2c_tag;
                     80:        iba.iba_bus_scan = maciic_scan;
                     81:        iba.iba_bus_scan_arg = &ca->ca_node;
                     82:        config_found(&sc->sc_dev, &iba, NULL);
                     83: }
                     84:
                     85: int
                     86: piic_i2c_acquire_bus(void *cookie, int flags)
                     87: {
                     88:        struct piic_softc *sc = cookie;
                     89:
                     90:        return (rw_enter(&sc->sc_buslock, RW_WRITE));
                     91: }
                     92:
                     93: void
                     94: piic_i2c_release_bus(void *cookie, int flags)
                     95: {
                     96:        struct piic_softc *sc = cookie;
                     97:
                     98:        rw_exit(&sc->sc_buslock);
                     99: }
                    100:
                    101: int
                    102: piic_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr,
                    103:     const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags)
                    104: {
                    105:        u_int8_t pmu_op = PMU_I2C_NORMAL;
                    106:        int retries = 10;
                    107:        PMData p;
                    108:
                    109:        if (!I2C_OP_STOP_P(op) || cmdlen > 1 || len > 5)
                    110:                return (EINVAL);
                    111:
                    112:        if (cmdlen == 0)
                    113:                pmu_op = PMU_I2C_SIMPLE;
                    114:        else if (I2C_OP_READ_P(op))
                    115:                pmu_op = PMU_I2C_COMBINED;
                    116:
                    117:        p.command = PMU_I2C;
                    118:        p.num_data = 7 + len;
                    119:        p.s_buf = p.r_buf = p.data;
                    120:
                    121:        p.data[0] = addr >> 7;  /* bus number */
                    122:        p.data[1] = pmu_op;
                    123:        p.data[2] = 0;
                    124:        p.data[3] = addr << 1;
                    125:        p.data[4] = *(u_int8_t *)cmdbuf;
                    126:        p.data[5] = addr << 1 | I2C_OP_READ_P(op);
                    127:        p.data[6] = len;
                    128:        memcpy(&p.data[7], buf, len);
                    129:
                    130:        if (pmgrop(&p))
                    131:                return (EIO);
                    132:
                    133:        while (retries--) {
                    134:                p.command = PMU_I2C;
                    135:                p.num_data = 1;
                    136:                p.s_buf = p.r_buf = p.data;
                    137:                p.data[0] = 0;
                    138:
                    139:                if (pmgrop(&p))
                    140:                        return (EIO);
                    141:
                    142:                if (p.data[0] == 1)
                    143:                        break;
                    144:
                    145:                DELAY(10 * 1000);
                    146:        }
                    147:
                    148:        if (I2C_OP_READ_P(op))
                    149:                memcpy(buf, &p.data[1], len);
                    150:        return (0);
                    151: }

CVSweb