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