xref: /freebsd/sys/dev/pcf/pcf.c (revision ba54cdcdda639bebc917b1796ecbc35a83ff8625)
1 /*-
2  * Copyright (c) 1998 Nicolas Souchu, Marc Bouget
3  * Copyright (c) 2004 Joerg Wunsch
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/module.h>
35 #include <sys/bus.h>
36 
37 #include <machine/bus.h>
38 #include <machine/resource.h>
39 
40 #include <sys/rman.h>
41 
42 #include <dev/iicbus/iiconf.h>
43 #include <dev/pcf/pcfvar.h>
44 #include "iicbus_if.h"
45 
46 /* Not so official debugging option. */
47 /* #define PCFDEBUG */
48 
49 static int pcf_wait_byte(struct pcf_softc *pcf);
50 static int pcf_noack(struct pcf_softc *pcf, int timeout);
51 
52 /*
53  * Polling mode for master operations wait for a new
54  * byte incomming or outgoing
55  */
56 int
57 pcf_wait_byte(struct pcf_softc *sc)
58 {
59 	int counter = TIMEOUT;
60 
61 	while (counter--) {
62 
63 		if ((pcf_get_S1(sc) & PIN) == 0)
64 			return (0);
65 	}
66 
67 #ifdef PCFDEBUG
68 	printf("pcf: timeout!\n");
69 #endif
70 
71 	return (IIC_ETIMEOUT);
72 }
73 
74 int
75 pcf_stop(device_t dev)
76 {
77 	struct pcf_softc *sc = DEVTOSOFTC(dev);
78 
79 #ifdef PCFDEBUG
80 	device_printf(dev, " >> stop\n");
81 #endif
82 	/*
83 	 * Send STOP condition iff the START condition was previously sent.
84 	 * STOP is sent only once even if an iicbus_stop() is called after
85 	 * an iicbus_read()... see pcf_read(): the PCF needs to send the stop
86 	 * before the last char is read.
87 	 */
88 	if (sc->pcf_started) {
89 		/* set stop condition and enable IT */
90 		pcf_set_S1(sc, PIN|ESO|ENI|STO|ACK);
91 
92 		sc->pcf_started = 0;
93 	}
94 
95 	return (0);
96 }
97 
98 
99 int
100 pcf_noack(struct pcf_softc *sc, int timeout)
101 {
102 	int noack;
103 	int k = timeout/10;
104 
105 	do {
106 		noack = pcf_get_S1(sc) & LRB;
107 		if (!noack)
108 			break;
109 		DELAY(10);				/* XXX wait 10 us */
110 	} while (k--);
111 
112 	return (noack);
113 }
114 
115 int
116 pcf_repeated_start(device_t dev, u_char slave, int timeout)
117 {
118 	struct pcf_softc *sc = DEVTOSOFTC(dev);
119 	int error = 0;
120 
121 #ifdef PCFDEBUG
122 	device_printf(dev, " >> repeated start for slave %#x\n",
123 		      (unsigned)slave);
124 #endif
125 	/* repeated start */
126 	pcf_set_S1(sc, ESO|STA|STO|ACK);
127 
128 	/* set slave address to PCF. Last bit (LSB) must be set correctly
129 	 * according to transfer direction */
130 	pcf_set_S0(sc, slave);
131 
132 	/* wait for address sent, polling */
133 	if ((error = pcf_wait_byte(sc)))
134 		goto error;
135 
136 	/* check for ack */
137 	if (pcf_noack(sc, timeout)) {
138 		error = IIC_ENOACK;
139 #ifdef PCFDEBUG
140 		printf("pcf: no ack on repeated_start!\n");
141 #endif
142 		goto error;
143 	}
144 
145 	return (0);
146 
147 error:
148 	pcf_stop(dev);
149 	return (error);
150 }
151 
152 int
153 pcf_start(device_t dev, u_char slave, int timeout)
154 {
155 	struct pcf_softc *sc = DEVTOSOFTC(dev);
156 	int error = 0;
157 
158 #ifdef PCFDEBUG
159 	device_printf(dev, " >> start for slave %#x\n", (unsigned)slave);
160 #endif
161 	if ((pcf_get_S1(sc) & nBB) == 0) {
162 #ifdef PCFDEBUG
163 		printf("pcf: busy!\n");
164 #endif
165 		return (IIC_EBUSBSY);
166 	}
167 
168 	/* set slave address to PCF. Last bit (LSB) must be set correctly
169 	 * according to transfer direction */
170 	pcf_set_S0(sc, slave);
171 
172 	/* START only */
173 	pcf_set_S1(sc, PIN|ESO|STA|ACK);
174 
175 	sc->pcf_started = 1;
176 
177 	/* wait for address sent, polling */
178 	if ((error = pcf_wait_byte(sc)))
179 		goto error;
180 
181 	/* check for ACK */
182 	if (pcf_noack(sc, timeout)) {
183 		error = IIC_ENOACK;
184 #ifdef PCFDEBUG
185 		printf("pcf: no ack on start!\n");
186 #endif
187 		goto error;
188 	}
189 
190 	return (0);
191 
192 error:
193 	pcf_stop(dev);
194 	return (error);
195 }
196 
197 void
198 pcf_intr(void *arg)
199 {
200 	struct pcf_softc *sc = arg;
201 	char data, status, addr;
202 	char error = 0;
203 
204 	status = pcf_get_S1(sc);
205 
206 	if (status & PIN) {
207 		printf("pcf: spurious interrupt, status=0x%x\n",
208 		       status & 0xff);
209 
210 		goto error;
211 	}
212 
213 	if (status & LAB)
214 		printf("pcf: bus arbitration lost!\n");
215 
216 	if (status & BER) {
217 		error = IIC_EBUSERR;
218 		iicbus_intr(sc->iicbus, INTR_ERROR, &error);
219 
220 		goto error;
221 	}
222 
223 	do {
224 		status = pcf_get_S1(sc);
225 
226 		switch(sc->pcf_slave_mode) {
227 
228 		case SLAVE_TRANSMITTER:
229 			if (status & LRB) {
230 				/* ack interrupt line */
231 				dummy_write(sc);
232 
233 				/* no ack, don't send anymore */
234 				sc->pcf_slave_mode = SLAVE_RECEIVER;
235 
236 				iicbus_intr(sc->iicbus, INTR_NOACK, NULL);
237 				break;
238 			}
239 
240 			/* get data from upper code */
241 			iicbus_intr(sc->iicbus, INTR_TRANSMIT, &data);
242 
243 			pcf_set_S0(sc, data);
244 			break;
245 
246 		case SLAVE_RECEIVER:
247 			if (status & AAS) {
248 				addr = pcf_get_S0(sc);
249 
250 				if (status & AD0)
251 					iicbus_intr(sc->iicbus, INTR_GENERAL, &addr);
252 				else
253 					iicbus_intr(sc->iicbus, INTR_START, &addr);
254 
255 				if (addr & LSB) {
256 					sc->pcf_slave_mode = SLAVE_TRANSMITTER;
257 
258 					/* get the first char from upper code */
259 					iicbus_intr(sc->iicbus, INTR_TRANSMIT, &data);
260 
261 					/* send first data byte */
262 					pcf_set_S0(sc, data);
263 				}
264 
265 				break;
266 			}
267 
268 			/* stop condition received? */
269 			if (status & STS) {
270 				/* ack interrupt line */
271 				dummy_read(sc);
272 
273 				/* emulate intr stop condition */
274 				iicbus_intr(sc->iicbus, INTR_STOP, NULL);
275 
276 			} else {
277 				/* get data, ack interrupt line */
278 				data = pcf_get_S0(sc);
279 
280 				/* deliver the character */
281 				iicbus_intr(sc->iicbus, INTR_RECEIVE, &data);
282 			}
283 			break;
284 
285 		    default:
286 			panic("%s: unknown slave mode (%d)!", __func__,
287 				sc->pcf_slave_mode);
288 		    }
289 
290 	} while ((pcf_get_S1(sc) & PIN) == 0);
291 
292 	return;
293 
294 error:
295 	/* unknown event on bus...reset PCF */
296 	pcf_set_S1(sc, PIN|ESO|ENI|ACK);
297 
298 	sc->pcf_slave_mode = SLAVE_RECEIVER;
299 
300 	return;
301 }
302 
303 int
304 pcf_rst_card(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
305 {
306 	struct pcf_softc *sc = DEVTOSOFTC(dev);
307 
308 	if (oldaddr)
309 		*oldaddr = sc->pcf_addr;
310 
311 	/* retrieve own address from bus level */
312 	if (!addr)
313 		sc->pcf_addr = PCF_DEFAULT_ADDR;
314 	else
315 		sc->pcf_addr = addr;
316 
317 	pcf_set_S1(sc, PIN);				/* initialize S1 */
318 
319 	/* own address S'O<>0 */
320 	pcf_set_S0(sc, sc->pcf_addr >> 1);
321 
322 	/* select clock register */
323 	pcf_set_S1(sc, PIN|ES1);
324 
325 	/* select bus speed : 18=90kb, 19=45kb, 1A=11kb, 1B=1.5kb */
326 	switch (speed) {
327 	case IIC_SLOW:
328 		pcf_set_S0(sc,  0x1b); /* XXX Sun uses 0x1f */
329 		break;
330 
331 	case IIC_FAST:
332 		pcf_set_S0(sc,  0x19); /* XXX Sun: 0x1d */
333 		break;
334 
335 	case IIC_UNKNOWN:
336 	case IIC_FASTEST:
337 	default:
338 		pcf_set_S0(sc,  0x18); /* XXX Sun: 0x1c */
339 		break;
340 	}
341 
342 	/* set bus on, ack=yes, INT=yes */
343 	pcf_set_S1(sc, PIN|ESO|ENI|ACK);
344 
345 	sc->pcf_slave_mode = SLAVE_RECEIVER;
346 
347 	return (0);
348 }
349 
350 int
351 pcf_write(device_t dev, char *buf, int len, int *sent, int timeout /* us */)
352 {
353 	struct pcf_softc *sc = DEVTOSOFTC(dev);
354 	int bytes, error = 0;
355 
356 #ifdef PCFDEBUG
357 	device_printf(dev, " >> writing %d bytes: %#x%s\n", len,
358 		      (unsigned)buf[0], len > 1? "...": "");
359 #endif
360 
361 	bytes = 0;
362 	while (len) {
363 
364 		pcf_set_S0(sc, *buf++);
365 
366 		/* wait for the byte to be send */
367 		if ((error = pcf_wait_byte(sc)))
368 			goto error;
369 
370 		/* check if ack received */
371 		if (pcf_noack(sc, timeout)) {
372 			error = IIC_ENOACK;
373 			goto error;
374 		}
375 
376 		len --;
377 		bytes ++;
378 	}
379 
380 error:
381 	*sent = bytes;
382 
383 #ifdef PCFDEBUG
384 	device_printf(dev, " >> %d bytes written (%d)\n", bytes, error);
385 #endif
386 
387 	return (error);
388 }
389 
390 int
391 pcf_read(device_t dev, char *buf, int len, int *read, int last,
392 	 int delay /* us */)
393 {
394 	struct pcf_softc *sc = DEVTOSOFTC(dev);
395 	int bytes, error = 0;
396 #ifdef PCFDEBUG
397 	char *obuf = buf;
398 
399 	device_printf(dev, " << reading %d bytes\n", len);
400 #endif
401 
402 	/* trig the bus to get the first data byte in S0 */
403 	if (len) {
404 		if (len == 1 && last)
405 			/* just one byte to read */
406 			pcf_set_S1(sc, ESO);		/* no ack */
407 
408 		dummy_read(sc);
409 	}
410 
411 	bytes = 0;
412 	while (len) {
413 
414 		/* XXX delay needed here */
415 
416 		/* wait for trigged byte */
417 		if ((error = pcf_wait_byte(sc))) {
418 			pcf_stop(dev);
419 			goto error;
420 		}
421 
422 		if (len == 1 && last)
423 			/* ok, last data byte already in S0, no I2C activity
424 			 * on next pcf_get_S0() */
425 			pcf_stop(dev);
426 
427 		else if (len == 2 && last)
428 			/* next trigged byte with no ack */
429 			pcf_set_S1(sc, ESO);
430 
431 		/* receive byte, trig next byte */
432 		*buf++ = pcf_get_S0(sc);
433 
434 		len --;
435 		bytes ++;
436 	};
437 
438 error:
439 	*read = bytes;
440 
441 #ifdef PCFDEBUG
442 	device_printf(dev, " << %d bytes read (%d): %#x%s\n", bytes, error,
443 		      (unsigned)obuf[0], bytes > 1? "...": "");
444 #endif
445 
446 	return (error);
447 }
448