Annotation of sys/arch/macppc/dev/piic.c, Revision 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