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