ki2c.c revision 1.1 1 /* $NetBSD: ki2c.c,v 1.1 2003/12/27 02:19:34 grant Exp $ */
2 /* Id: ki2c.c,v 1.7 2002/10/05 09:56:05 tsubai Exp */
3
4 /*-
5 * Copyright (c) 2001 Tsubai Masanari. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include <sys/param.h>
31 #include <sys/device.h>
32 #include <sys/systm.h>
33
34 #include <dev/ofw/openfirm.h>
35 #include <uvm/uvm_extern.h>
36 #include <machine/autoconf.h>
37
38 /* Keywest I2C Register offsets */
39 #define MODE 0
40 #define CONTROL 1
41 #define STATUS 2
42 #define ISR 3
43 #define IER 4
44 #define ADDR 5
45 #define SUBADDR 6
46 #define DATA 7
47
48 /* MODE */
49 #define I2C_SPEED 0x03 /* Speed mask */
50 #define I2C_100kHz 0x00
51 #define I2C_50kHz 0x01
52 #define I2C_25kHz 0x02
53 #define I2C_MODE 0x0c /* Mode mask */
54 #define I2C_DUMBMODE 0x00 /* Dumb mode */
55 #define I2C_STDMODE 0x04 /* Standard mode */
56 #define I2C_STDSUBMODE 0x08 /* Standard mode + sub address */
57 #define I2C_COMBMODE 0x0c /* Combined mode */
58 #define I2C_PORT 0xf0 /* Port mask */
59
60 /* CONTROL */
61 #define I2C_CT_AAK 0x01 /* Send AAK */
62 #define I2C_CT_ADDR 0x02 /* Send address(es) */
63 #define I2C_CT_STOP 0x04 /* Send STOP */
64 #define I2C_CT_START 0x08 /* Send START */
65
66 /* STATUS */
67 #define I2C_ST_BUSY 0x01 /* Busy */
68 #define I2C_ST_LASTAAK 0x02 /* Last AAK */
69 #define I2C_ST_LASTRW 0x04 /* Last R/W */
70 #define I2C_ST_SDA 0x08 /* SDA */
71 #define I2C_ST_SCL 0x10 /* SCL */
72
73 /* ISR/IER */
74 #define I2C_INT_DATA 0x01 /* Data byte sent/received */
75 #define I2C_INT_ADDR 0x02 /* Address sent */
76 #define I2C_INT_STOP 0x04 /* STOP condition sent */
77 #define I2C_INT_START 0x08 /* START condition sent */
78
79 /* I2C flags */
80 #define I2C_BUSY 0x01
81 #define I2C_READING 0x02
82 #define I2C_ERROR 0x04
83
84 struct ki2c_softc {
85 struct device sc_dev;
86 u_char *sc_reg;
87 int sc_regstep;
88
89 int sc_flags;
90 u_char *sc_data;
91 int sc_resid;
92 };
93
94 int ki2c_match(struct device *, struct cfdata *, void *);
95 void ki2c_attach(struct device *, struct device *, void *);
96 inline u_int ki2c_readreg(struct ki2c_softc *, int);
97 inline void ki2c_writereg(struct ki2c_softc *, int, u_int);
98 u_int ki2c_getmode(struct ki2c_softc *);
99 void ki2c_setmode(struct ki2c_softc *, u_int);
100 u_int ki2c_getspeed(struct ki2c_softc *);
101 void ki2c_setspeed(struct ki2c_softc *, u_int);
102 int ki2c_intr(struct ki2c_softc *);
103 int ki2c_poll(struct ki2c_softc *, int);
104 int ki2c_start(struct ki2c_softc *, int, int, void *, int);
105 int ki2c_read(struct ki2c_softc *, int, int, void *, int);
106 int ki2c_write(struct ki2c_softc *, int, int, const void *, int);
107
108 struct cfattach ki2c_ca = {
109 "ki2c", {}, sizeof(struct ki2c_softc), ki2c_match, ki2c_attach
110 };
111
112 int
113 ki2c_match(parent, match, aux)
114 struct device *parent;
115 struct cfdata *match;
116 void *aux;
117 {
118 struct confargs *ca = aux;
119
120 if (strcmp(ca->ca_name, "i2c") == 0)
121 return 1;
122
123 return 0;
124 }
125
126 void
127 ki2c_attach(parent, self, aux)
128 struct device *parent;
129 struct device *self;
130 void *aux;
131 {
132 struct ki2c_softc *sc = (struct ki2c_softc *)self;
133 struct confargs *ca = aux;
134 int node = ca->ca_node;
135 int rate;
136
137 ca->ca_reg[0] += ca->ca_baseaddr;
138
139 if (OF_getprop(node, "AAPL,i2c-rate", &rate, 4) != 4) {
140 printf(": cannot get i2c-rate\n");
141 return;
142 }
143 if (OF_getprop(node, "AAPL,address", &sc->sc_reg, 4) != 4) {
144 printf(": unable to find i2c address\n");
145 return;
146 }
147 if (OF_getprop(node, "AAPL,address-step", &sc->sc_regstep, 4) != 4) {
148 printf(": unable to find i2c address step\n");
149 return;
150 }
151
152 printf("\n");
153
154 ki2c_writereg(sc, STATUS, 0);
155 ki2c_writereg(sc, ISR, 0);
156 ki2c_writereg(sc, IER, 0);
157
158 ki2c_setmode(sc, I2C_STDSUBMODE);
159 ki2c_setspeed(sc, I2C_100kHz); /* XXX rate */
160 }
161
162 u_int
163 ki2c_readreg(sc, reg)
164 struct ki2c_softc *sc;
165 int reg;
166 {
167 u_char *addr = sc->sc_reg + sc->sc_regstep * reg;
168
169 return *addr;
170 }
171
172 void
173 ki2c_writereg(sc, reg, val)
174 struct ki2c_softc *sc;
175 int reg;
176 u_int val;
177 {
178 u_char *addr = sc->sc_reg + sc->sc_regstep * reg;
179
180 *addr = val;
181 asm volatile ("eieio");
182 delay(10);
183 }
184
185 u_int
186 ki2c_getmode(sc)
187 struct ki2c_softc *sc;
188 {
189 return ki2c_readreg(sc, MODE) & I2C_MODE;
190 }
191
192 void
193 ki2c_setmode(sc, mode)
194 struct ki2c_softc *sc;
195 u_int mode;
196 {
197 u_int x;
198
199 KASSERT((mode & ~I2C_MODE) == 0);
200 x = ki2c_readreg(sc, MODE);
201 x &= ~I2C_MODE;
202 x |= mode;
203 ki2c_writereg(sc, MODE, x);
204 }
205
206 u_int
207 ki2c_getspeed(sc)
208 struct ki2c_softc *sc;
209 {
210 return ki2c_readreg(sc, MODE) & I2C_SPEED;
211 }
212
213 void
214 ki2c_setspeed(sc, speed)
215 struct ki2c_softc *sc;
216 u_int speed;
217 {
218 u_int x;
219
220 KASSERT((speed & ~I2C_SPEED) == 0);
221 x = ki2c_readreg(sc, MODE);
222 x &= ~I2C_SPEED;
223 x |= speed;
224 ki2c_writereg(sc, MODE, x);
225 }
226
227 int
228 ki2c_intr(sc)
229 struct ki2c_softc *sc;
230 {
231 u_int isr, x;
232
233 isr = ki2c_readreg(sc, ISR);
234
235 if (isr & I2C_INT_ADDR) {
236 #if 0
237 if ((ki2c_readreg(sc, STATUS) & I2C_ST_LASTAAK) == 0) {
238 /* No slave responded. */
239 sc->sc_flags |= I2C_ERROR;
240 goto out;
241 }
242 #endif
243
244 if (sc->sc_flags & I2C_READING) {
245 if (sc->sc_resid > 1) {
246 x = ki2c_readreg(sc, CONTROL);
247 x |= I2C_CT_AAK;
248 ki2c_writereg(sc, CONTROL, x);
249 }
250 } else {
251 ki2c_writereg(sc, DATA, *sc->sc_data++);
252 sc->sc_resid--;
253 }
254 }
255
256 if (isr & I2C_INT_DATA) {
257 if (sc->sc_flags & I2C_READING) {
258 *sc->sc_data++ = ki2c_readreg(sc, DATA);
259 sc->sc_resid--;
260
261 if (sc->sc_resid == 0) { /* Completed */
262 ki2c_writereg(sc, CONTROL, 0);
263 goto out;
264 }
265 } else {
266 #if 0
267 if ((ki2c_readreg(sc, STATUS) & I2C_ST_LASTAAK) == 0) {
268 /* No slave responded. */
269 sc->sc_flags |= I2C_ERROR;
270 goto out;
271 }
272 #endif
273
274 if (sc->sc_resid == 0) {
275 x = ki2c_readreg(sc, CONTROL) | I2C_CT_STOP;
276 ki2c_writereg(sc, CONTROL, x);
277 } else {
278 ki2c_writereg(sc, DATA, *sc->sc_data++);
279 sc->sc_resid--;
280 }
281 }
282 }
283
284 out:
285 if (isr & I2C_INT_STOP) {
286 ki2c_writereg(sc, CONTROL, 0);
287 sc->sc_flags &= ~I2C_BUSY;
288 }
289
290 ki2c_writereg(sc, ISR, isr);
291
292 return 1;
293 }
294
295 int
296 ki2c_poll(sc, timo)
297 struct ki2c_softc *sc;
298 int timo;
299 {
300 while (sc->sc_flags & I2C_BUSY) {
301 if (ki2c_readreg(sc, ISR))
302 ki2c_intr(sc);
303 timo -= 100;
304 if (timo < 0) {
305 printf("i2c_poll: timeout\n");
306 return -1;
307 }
308 delay(100);
309 }
310 return 0;
311 }
312
313 int
314 ki2c_start(sc, addr, subaddr, data, len)
315 struct ki2c_softc *sc;
316 int addr, subaddr, len;
317 void *data;
318 {
319 int rw = (sc->sc_flags & I2C_READING) ? 1 : 0;
320 int timo, x;
321
322 KASSERT((addr & 1) == 0);
323
324 sc->sc_data = data;
325 sc->sc_resid = len;
326 sc->sc_flags |= I2C_BUSY;
327
328 timo = 1000 + len * 200;
329
330 /* XXX TAS3001 sometimes takes 50ms to finish writing registers. */
331 /* if (addr == 0x68) */
332 timo += 100000;
333
334 ki2c_writereg(sc, ADDR, addr | rw);
335 ki2c_writereg(sc, SUBADDR, subaddr);
336
337 x = ki2c_readreg(sc, CONTROL) | I2C_CT_ADDR;
338 ki2c_writereg(sc, CONTROL, x);
339
340 if (ki2c_poll(sc, timo))
341 return -1;
342 if (sc->sc_flags & I2C_ERROR) {
343 printf("I2C_ERROR\n");
344 return -1;
345 }
346 return 0;
347 }
348
349 int
350 ki2c_read(sc, addr, subaddr, data, len)
351 struct ki2c_softc *sc;
352 int addr, subaddr, len;
353 void *data;
354 {
355 sc->sc_flags = I2C_READING;
356 return ki2c_start(sc, addr, subaddr, data, len);
357 }
358
359 int
360 ki2c_write(sc, addr, subaddr, data, len)
361 struct ki2c_softc *sc;
362 int addr, subaddr, len;
363 const void *data;
364 {
365 sc->sc_flags = 0;
366 return ki2c_start(sc, addr, subaddr, (void *)data, len);
367 }
368