xref: /freebsd/sys/dev/pcf/pcf.c (revision 9a14aa017b21c292740c00ee098195cd46642730)
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/bus.h>
33 #include <sys/lock.h>
34 #include <sys/kernel.h>
35 #include <sys/module.h>
36 #include <sys/mutex.h>
37 #include <sys/systm.h>
38 
39 #include <machine/bus.h>
40 #include <machine/resource.h>
41 
42 #include <sys/rman.h>
43 
44 #include <dev/iicbus/iicbus.h>
45 #include <dev/iicbus/iiconf.h>
46 #include <dev/pcf/pcfvar.h>
47 #include "iicbus_if.h"
48 
49 /* Not so official debugging option. */
50 /* #define PCFDEBUG */
51 
52 static int pcf_wait_byte(struct pcf_softc *pcf);
53 static int pcf_noack(struct pcf_softc *pcf, int timeout);
54 static void pcf_stop_locked(struct pcf_softc *pcf);
55 
56 /*
57  * Polling mode for master operations wait for a new
58  * byte incoming or outgoing
59  */
60 static int
61 pcf_wait_byte(struct pcf_softc *sc)
62 {
63 	int counter = TIMEOUT;
64 
65 	PCF_ASSERT_LOCKED(sc);
66 	while (counter--) {
67 
68 		if ((pcf_get_S1(sc) & PIN) == 0)
69 			return (0);
70 	}
71 
72 #ifdef PCFDEBUG
73 	printf("pcf: timeout!\n");
74 #endif
75 
76 	return (IIC_ETIMEOUT);
77 }
78 
79 static void
80 pcf_stop_locked(struct pcf_softc *sc)
81 {
82 
83 	PCF_ASSERT_LOCKED(sc);
84 #ifdef PCFDEBUG
85 	device_printf(dev, " >> stop\n");
86 #endif
87 	/*
88 	 * Send STOP condition iff the START condition was previously sent.
89 	 * STOP is sent only once even if an iicbus_stop() is called after
90 	 * an iicbus_read()... see pcf_read(): the PCF needs to send the stop
91 	 * before the last char is read.
92 	 */
93 	if (sc->pcf_started) {
94 		/* set stop condition and enable IT */
95 		pcf_set_S1(sc, PIN|ESO|ENI|STO|ACK);
96 
97 		sc->pcf_started = 0;
98 	}
99 }
100 
101 static int
102 pcf_noack(struct pcf_softc *sc, int timeout)
103 {
104 	int noack;
105 	int k = timeout/10;
106 
107 	PCF_ASSERT_LOCKED(sc);
108 	do {
109 		noack = pcf_get_S1(sc) & LRB;
110 		if (!noack)
111 			break;
112 		DELAY(10);				/* XXX wait 10 us */
113 	} while (k--);
114 
115 	return (noack);
116 }
117 
118 int
119 pcf_repeated_start(device_t dev, u_char slave, int timeout)
120 {
121 	struct pcf_softc *sc = DEVTOSOFTC(dev);
122 	int error = 0;
123 
124 	PCF_LOCK(sc);
125 #ifdef PCFDEBUG
126 	device_printf(dev, " >> repeated start for slave %#x\n",
127 		      (unsigned)slave);
128 #endif
129 	/* repeated start */
130 	pcf_set_S1(sc, ESO|STA|STO|ACK);
131 
132 	/* set slave address to PCF. Last bit (LSB) must be set correctly
133 	 * according to transfer direction */
134 	pcf_set_S0(sc, slave);
135 
136 	/* wait for address sent, polling */
137 	if ((error = pcf_wait_byte(sc)))
138 		goto error;
139 
140 	/* check for ack */
141 	if (pcf_noack(sc, timeout)) {
142 		error = IIC_ENOACK;
143 #ifdef PCFDEBUG
144 		printf("pcf: no ack on repeated_start!\n");
145 #endif
146 		goto error;
147 	}
148 
149 	PCF_UNLOCK(sc);
150 	return (0);
151 
152 error:
153 	pcf_stop_locked(sc);
154 	PCF_UNLOCK(sc);
155 	return (error);
156 }
157 
158 int
159 pcf_start(device_t dev, u_char slave, int timeout)
160 {
161 	struct pcf_softc *sc = DEVTOSOFTC(dev);
162 	int error = 0;
163 
164 	PCF_LOCK(sc);
165 #ifdef PCFDEBUG
166 	device_printf(dev, " >> start for slave %#x\n", (unsigned)slave);
167 #endif
168 	if ((pcf_get_S1(sc) & nBB) == 0) {
169 #ifdef PCFDEBUG
170 		printf("pcf: busy!\n");
171 #endif
172 		PCF_UNLOCK(sc);
173 		return (IIC_EBUSBSY);
174 	}
175 
176 	/* set slave address to PCF. Last bit (LSB) must be set correctly
177 	 * according to transfer direction */
178 	pcf_set_S0(sc, slave);
179 
180 	/* START only */
181 	pcf_set_S1(sc, PIN|ESO|STA|ACK);
182 
183 	sc->pcf_started = 1;
184 
185 	/* wait for address sent, polling */
186 	if ((error = pcf_wait_byte(sc)))
187 		goto error;
188 
189 	/* check for ACK */
190 	if (pcf_noack(sc, timeout)) {
191 		error = IIC_ENOACK;
192 #ifdef PCFDEBUG
193 		printf("pcf: no ack on start!\n");
194 #endif
195 		goto error;
196 	}
197 
198 	PCF_UNLOCK(sc);
199 	return (0);
200 
201 error:
202 	pcf_stop_locked(sc);
203 	PCF_UNLOCK(sc);
204 	return (error);
205 }
206 
207 int
208 pcf_stop(device_t dev)
209 {
210 	struct pcf_softc *sc = DEVTOSOFTC(dev);
211 
212 #ifdef PCFDEBUG
213 	device_printf(dev, " >> stop\n");
214 #endif
215 	PCF_LOCK(sc);
216 	pcf_stop_locked(sc);
217 	PCF_UNLOCK(sc);
218 
219 	return (0);
220 }
221 
222 void
223 pcf_intr(void *arg)
224 {
225 	struct pcf_softc *sc = arg;
226 	char data, status, addr;
227 	char error = 0;
228 
229 	PCF_LOCK(sc);
230 	status = pcf_get_S1(sc);
231 
232 	if (status & PIN) {
233 		printf("pcf: spurious interrupt, status=0x%x\n",
234 		       status & 0xff);
235 
236 		goto error;
237 	}
238 
239 	if (status & LAB)
240 		printf("pcf: bus arbitration lost!\n");
241 
242 	if (status & BER) {
243 		error = IIC_EBUSERR;
244 		iicbus_intr(sc->iicbus, INTR_ERROR, &error);
245 
246 		goto error;
247 	}
248 
249 	do {
250 		status = pcf_get_S1(sc);
251 
252 		switch(sc->pcf_slave_mode) {
253 
254 		case SLAVE_TRANSMITTER:
255 			if (status & LRB) {
256 				/* ack interrupt line */
257 				dummy_write(sc);
258 
259 				/* no ack, don't send anymore */
260 				sc->pcf_slave_mode = SLAVE_RECEIVER;
261 
262 				iicbus_intr(sc->iicbus, INTR_NOACK, NULL);
263 				break;
264 			}
265 
266 			/* get data from upper code */
267 			iicbus_intr(sc->iicbus, INTR_TRANSMIT, &data);
268 
269 			pcf_set_S0(sc, data);
270 			break;
271 
272 		case SLAVE_RECEIVER:
273 			if (status & AAS) {
274 				addr = pcf_get_S0(sc);
275 
276 				if (status & AD0)
277 					iicbus_intr(sc->iicbus, INTR_GENERAL, &addr);
278 				else
279 					iicbus_intr(sc->iicbus, INTR_START, &addr);
280 
281 				if (addr & LSB) {
282 					sc->pcf_slave_mode = SLAVE_TRANSMITTER;
283 
284 					/* get the first char from upper code */
285 					iicbus_intr(sc->iicbus, INTR_TRANSMIT, &data);
286 
287 					/* send first data byte */
288 					pcf_set_S0(sc, data);
289 				}
290 
291 				break;
292 			}
293 
294 			/* stop condition received? */
295 			if (status & STS) {
296 				/* ack interrupt line */
297 				dummy_read(sc);
298 
299 				/* emulate intr stop condition */
300 				iicbus_intr(sc->iicbus, INTR_STOP, NULL);
301 
302 			} else {
303 				/* get data, ack interrupt line */
304 				data = pcf_get_S0(sc);
305 
306 				/* deliver the character */
307 				iicbus_intr(sc->iicbus, INTR_RECEIVE, &data);
308 			}
309 			break;
310 
311 		    default:
312 			panic("%s: unknown slave mode (%d)!", __func__,
313 				sc->pcf_slave_mode);
314 		    }
315 
316 	} while ((pcf_get_S1(sc) & PIN) == 0);
317 	PCF_UNLOCK(sc);
318 
319 	return;
320 
321 error:
322 	/* unknown event on bus...reset PCF */
323 	pcf_set_S1(sc, PIN|ESO|ENI|ACK);
324 
325 	sc->pcf_slave_mode = SLAVE_RECEIVER;
326 	PCF_UNLOCK(sc);
327 
328 	return;
329 }
330 
331 int
332 pcf_rst_card(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
333 {
334 	struct pcf_softc *sc = DEVTOSOFTC(dev);
335 
336 	PCF_LOCK(sc);
337 	if (oldaddr)
338 		*oldaddr = sc->pcf_addr;
339 
340 	/* retrieve own address from bus level */
341 	if (!addr)
342 		sc->pcf_addr = PCF_DEFAULT_ADDR;
343 	else
344 		sc->pcf_addr = addr;
345 
346 	pcf_set_S1(sc, PIN);				/* initialize S1 */
347 
348 	/* own address S'O<>0 */
349 	pcf_set_S0(sc, sc->pcf_addr >> 1);
350 
351 	/* select clock register */
352 	pcf_set_S1(sc, PIN|ES1);
353 
354 	/* select bus speed : 18=90kb, 19=45kb, 1A=11kb, 1B=1.5kb */
355 	switch (speed) {
356 	case IIC_SLOW:
357 		pcf_set_S0(sc,  0x1b); /* XXX Sun uses 0x1f */
358 		break;
359 
360 	case IIC_FAST:
361 		pcf_set_S0(sc,  0x19); /* XXX Sun: 0x1d */
362 		break;
363 
364 	case IIC_UNKNOWN:
365 	case IIC_FASTEST:
366 	default:
367 		pcf_set_S0(sc,  0x18); /* XXX Sun: 0x1c */
368 		break;
369 	}
370 
371 	/* set bus on, ack=yes, INT=yes */
372 	pcf_set_S1(sc, PIN|ESO|ENI|ACK);
373 
374 	sc->pcf_slave_mode = SLAVE_RECEIVER;
375 	PCF_UNLOCK(sc);
376 
377 	return (0);
378 }
379 
380 int
381 pcf_write(device_t dev, const char *buf, int len, int *sent, int timeout /* us */)
382 {
383 	struct pcf_softc *sc = DEVTOSOFTC(dev);
384 	int bytes, error = 0;
385 
386 #ifdef PCFDEBUG
387 	device_printf(dev, " >> writing %d bytes: %#x%s\n", len,
388 		      (unsigned)buf[0], len > 1? "...": "");
389 #endif
390 
391 	bytes = 0;
392 	PCF_LOCK(sc);
393 	while (len) {
394 
395 		pcf_set_S0(sc, *buf++);
396 
397 		/* wait for the byte to be send */
398 		if ((error = pcf_wait_byte(sc)))
399 			goto error;
400 
401 		/* check if ack received */
402 		if (pcf_noack(sc, timeout)) {
403 			error = IIC_ENOACK;
404 			goto error;
405 		}
406 
407 		len --;
408 		bytes ++;
409 	}
410 
411 error:
412 	*sent = bytes;
413 	PCF_UNLOCK(sc);
414 
415 #ifdef PCFDEBUG
416 	device_printf(dev, " >> %d bytes written (%d)\n", bytes, error);
417 #endif
418 
419 	return (error);
420 }
421 
422 int
423 pcf_read(device_t dev, char *buf, int len, int *read, int last,
424 	 int delay /* us */)
425 {
426 	struct pcf_softc *sc = DEVTOSOFTC(dev);
427 	int bytes, error = 0;
428 #ifdef PCFDEBUG
429 	char *obuf = buf;
430 
431 	device_printf(dev, " << reading %d bytes\n", len);
432 #endif
433 
434 	PCF_LOCK(sc);
435 	/* trig the bus to get the first data byte in S0 */
436 	if (len) {
437 		if (len == 1 && last)
438 			/* just one byte to read */
439 			pcf_set_S1(sc, ESO);		/* no ack */
440 
441 		dummy_read(sc);
442 	}
443 
444 	bytes = 0;
445 	while (len) {
446 
447 		/* XXX delay needed here */
448 
449 		/* wait for trigged byte */
450 		if ((error = pcf_wait_byte(sc))) {
451 			pcf_stop_locked(sc);
452 			goto error;
453 		}
454 
455 		if (len == 1 && last)
456 			/* ok, last data byte already in S0, no I2C activity
457 			 * on next pcf_get_S0() */
458 			pcf_stop_locked(sc);
459 
460 		else if (len == 2 && last)
461 			/* next trigged byte with no ack */
462 			pcf_set_S1(sc, ESO);
463 
464 		/* receive byte, trig next byte */
465 		*buf++ = pcf_get_S0(sc);
466 
467 		len --;
468 		bytes ++;
469 	};
470 
471 error:
472 	*read = bytes;
473 	PCF_UNLOCK(sc);
474 
475 #ifdef PCFDEBUG
476 	device_printf(dev, " << %d bytes read (%d): %#x%s\n", bytes, error,
477 		      (unsigned)obuf[0], bytes > 1? "...": "");
478 #endif
479 
480 	return (error);
481 }
482 
483 DRIVER_MODULE(iicbus, pcf, iicbus_driver, iicbus_devclass, 0, 0);
484 MODULE_DEPEND(pcf, iicbus, PCF_MINVER, PCF_PREFVER, PCF_MAXVER);
485 MODULE_VERSION(pcf, PCF_MODVER);
486