xref: /netbsd-src/sys/arch/macppc/dev/ki2c.c (revision de1dfb1250df962f1ff3a011772cf58e605aed11)
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