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