xref: /freebsd/sys/dev/pcf/pcf.c (revision a8445737e740901f5f2c8d24c12ef7fc8b00134e)
1 /*-
2  * Copyright (c) 1998 Nicolas Souchu, Marc Bouget
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *	$Id: pcf.c,v 1.1.1.17 1998/08/29 17:04:23 son Exp $
27  *
28  */
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/kernel.h>
32 #include <sys/module.h>
33 #include <sys/bus.h>
34 #include <sys/conf.h>
35 #include <sys/malloc.h>
36 
37 #include <machine/clock.h>
38 
39 #include <i386/isa/isa_device.h>
40 
41 #include <dev/iicbus/iiconf.h>
42 #include "iicbus_if.h"
43 
44 #define TIMEOUT	99999					/* XXX */
45 
46 /* Status bits of S1 register (read only) */
47 #define nBB	0x01		/* busy when low set/reset by STOP/START*/
48 #define LAB	0x02		/* lost arbitration bit in multi-master mode */
49 #define AAS	0x04		/* addressed as slave */
50 #define LRB	0x08		/* last received byte when not AAS */
51 #define AD0	0x08		/* general call received when AAS */
52 #define BER	0x10		/* bus error, misplaced START or STOP */
53 #define STS	0x20		/* STOP detected in slave receiver mode */
54 #define PIN	0x80		/* pending interrupt not (r/w) */
55 
56 /* Control bits of S1 register (write only) */
57 #define ACK	0x01
58 #define STO	0x02
59 #define STA	0x04
60 #define ENI	0x08
61 #define ES2	0x10
62 #define ES1	0x20
63 #define ES0	0x40
64 
65 #define BUFSIZE 2048
66 
67 #define SLAVE_TRANSMITTER	0x1
68 #define SLAVE_RECEIVER		0x2
69 
70 struct pcf_softc {
71 
72 	int pcf_base;			/* isa port */
73 
74 	int pcf_count;
75 	int pcf_own_address;		/* own address */
76 	int pcf_slave_mode;		/* receiver or transmitter */
77 
78 	device_t iicbus;		/* the corresponding iicbus */
79 };
80 
81 struct pcf_isa_softc {
82 
83 	int pcf_unit;			/* unit of the isa device */
84 	int pcf_base;			/* isa port */
85 	int pcf_irq;			/* isa irq or null if polled */
86 
87 	unsigned int pcf_flags;		/* boot flags */
88 };
89 
90 #define MAXPCF 2
91 
92 static struct pcf_isa_softc *pcfdata[MAXPCF];
93 static npcf = 0;
94 
95 static int	pcfprobe_isa(struct isa_device *);
96 static int	pcfattach_isa(struct isa_device *);
97 
98 struct isa_driver pcfdriver = {
99 	pcfprobe_isa, pcfattach_isa, "pcf"
100 };
101 
102 static int pcf_probe(device_t);
103 static int pcf_attach(device_t);
104 static void pcf_print_child(device_t, device_t);
105 
106 static int pcf_repeated_start(device_t, u_char);
107 static int pcf_start(device_t, u_char);
108 static int pcf_stop(device_t);
109 static int pcf_write(device_t, char *, int, int *);
110 static int pcf_read(device_t, char *, int, int *);
111 static int pcf_rst_card(device_t, u_char);
112 
113 static device_method_t pcf_methods[] = {
114 	/* device interface */
115 	DEVMETHOD(device_probe,		pcf_probe),
116 	DEVMETHOD(device_attach,	pcf_attach),
117 
118 	/* bus interface */
119 	DEVMETHOD(bus_print_child,	pcf_print_child),
120 
121 	/* iicbus interface */
122 	DEVMETHOD(iicbus_repeated_start, pcf_repeated_start),
123 	DEVMETHOD(iicbus_start,		pcf_start),
124 	DEVMETHOD(iicbus_stop,		pcf_stop),
125 	DEVMETHOD(iicbus_write,		pcf_write),
126 	DEVMETHOD(iicbus_read,		pcf_read),
127 	DEVMETHOD(iicbus_reset,		pcf_rst_card),
128 
129 	{ 0, 0 }
130 };
131 
132 static driver_t pcf_driver = {
133 	"pcf",
134 	pcf_methods,
135 	DRIVER_TYPE_MISC,
136 	sizeof(struct pcf_softc),
137 };
138 
139 static devclass_t pcf_devclass;
140 
141 #define DEVTOSOFTC(dev) ((struct pcf_softc *)device_get_softc(dev))
142 
143 static int
144 pcfprobe_isa(struct isa_device *dvp)
145 {
146 	device_t pcfdev;
147 	struct pcf_isa_softc *pcf;
148 	int error;
149 
150 	if (npcf >= MAXPCF)
151 		return (0);
152 
153 	if ((pcf = (struct pcf_isa_softc *)malloc(sizeof(struct pcf_isa_softc),
154 			M_DEVBUF, M_NOWAIT)) == NULL)
155 		return (0);
156 
157 	pcf->pcf_base = dvp->id_iobase;		/* XXX should be ivars */
158 	pcf->pcf_unit = dvp->id_unit;
159 
160 	if (!(dvp->id_flags & IIC_POLLED))
161 		pcf->pcf_irq = (dvp->id_irq);
162 
163 	pcfdata[npcf++] = pcf;
164 
165 	/* XXX add the pcf device to the root_bus until isa bus exists */
166 	pcfdev = device_add_child(root_bus, "pcf", pcf->pcf_unit, NULL);
167 
168 	if (!pcfdev)
169 		goto error;
170 
171 end_probe:
172 	return (1);
173 
174 error:
175 	free(pcf, M_DEVBUF);
176 	return (0);
177 }
178 
179 static int
180 pcfattach_isa(struct isa_device *isdp)
181 {
182 	return (1);				/* ok */
183 }
184 
185 static int
186 pcf_probe(device_t pcfdev)
187 {
188 	struct pcf_softc *pcf = (struct pcf_softc *)device_get_softc(pcfdev);
189 
190 	/* XXX try do detect chipset */
191 
192 	device_set_desc(pcfdev, "PCF8584 I2C bus controller");
193 
194 	pcf->iicbus = iicbus_alloc_bus(pcfdev);
195 
196 	if (!pcf->iicbus)
197 		return (EINVAL);
198 
199 	return (0);
200 }
201 
202 static int
203 pcf_attach(device_t pcfdev)
204 {
205 	struct pcf_softc *pcf = (struct pcf_softc *)device_get_softc(pcfdev);
206 	int unit = device_get_unit(pcfdev);
207 
208 	/* retrieve base address from isa initialization
209 	 *
210 	 * XXX should use ivars with isabus
211 	 */
212 	pcf->pcf_base = pcfdata[unit]->pcf_base;
213 
214 	/* probe and attach the iicbus */
215 	device_probe_and_attach(pcf->iicbus);
216 
217 	return (0);
218 }
219 
220 static void
221 pcf_print_child(device_t bus, device_t dev)
222 {
223 	printf(" on %s%d addr 0x%x", device_get_name(bus),
224 		device_get_unit(bus), iicbus_get_own_address(dev));
225 
226 	return;
227 }
228 
229 /*
230  * PCF8584 datasheet : when operate at 8 MHz or more, a minimun time of
231  * 6 clocks cycles must be left between two consecutives access
232  */
233 #define pcf_nops()	DELAY(10)
234 
235 #define dummy_read(pcf)		PCF_GET_S0(pcf)
236 #define dummy_write(pcf)	PCF_SET_S0(pcf, 0)
237 
238 /*
239  * Specific register access to PCF8584
240  */
241 static void PCF_SET_S0(struct pcf_softc *pcf, int data)
242 {
243 	outb(pcf->pcf_base, data);
244 	pcf_nops();
245 }
246 
247 static void PCF_SET_S1(struct pcf_softc *pcf, int data)
248 {
249 	outb(pcf->pcf_base+1, data);
250 	pcf_nops();
251 }
252 
253 static char PCF_GET_S0(struct pcf_softc *pcf)
254 {
255 	char data;
256 
257 	data = inb(pcf->pcf_base);
258 	pcf_nops();
259 
260 	return (data);
261 }
262 
263 static char PCF_GET_S1(struct pcf_softc *pcf)
264 {
265 	char data;
266 
267 	data = inb(pcf->pcf_base+1);
268 	pcf_nops();
269 
270 	return (data);
271 }
272 
273 /*
274  * Polling mode for master operations wait for a new
275  * byte incomming or outgoing
276  */
277 static int pcf_wait_byte(struct pcf_softc *pcf)
278 {
279 	int counter = TIMEOUT;
280 
281 	while (counter--) {
282 
283 		if ((PCF_GET_S1(pcf) & PIN) == 0)
284 			return (0);
285 	}
286 
287 	return (IIC_ETIMEOUT);
288 }
289 
290 static int pcf_stop(device_t pcfdev)
291 {
292 	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
293 
294 	/* set stop condition and enable IT */
295 	PCF_SET_S1(pcf, PIN|ES0|ENI|STO|ACK);
296 
297 	return (0);
298 }
299 
300 static int pcf_repeated_start(device_t pcfdev, u_char slave)
301 {
302 	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
303 	int error = 0;
304 
305 	/* repeated start */
306 	PCF_SET_S1(pcf, ES0|STA|STO|ACK);
307 
308 	/* set slave address to PCF. Last bit (LSB) must be set correctly
309 	 * according to transfer direction */
310 	PCF_SET_S0(pcf, slave);
311 
312 	/* wait for address sent, polling */
313 	if ((error = pcf_wait_byte(pcf)))
314 		goto error;
315 
316 	/* check ACK */
317 	if (PCF_GET_S1(pcf) & LRB) {
318 		error = IIC_ENOACK;
319 		goto error;
320 	}
321 
322 	return (0);
323 
324 error:
325 	pcf_stop(pcfdev);
326 	return (error);
327 }
328 
329 static int pcf_start(device_t pcfdev, u_char slave)
330 {
331 	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
332 	int error = 0;
333 
334 	if (PCF_GET_S1(pcf) & nBB == 0)
335 		return (IIC_EBUSBSY);
336 
337 	/* set slave address to PCF. Last bit (LSB) must be set correctly
338 	 * according to transfer direction */
339 	PCF_SET_S0(pcf, slave);
340 
341 	/* START only */
342 	PCF_SET_S1(pcf, PIN|ES0|STA|ACK);
343 
344 	/* wait for address sent, polling */
345 	if ((error = pcf_wait_byte(pcf)))
346 		goto error;
347 
348 	/* check ACK */
349 	if (PCF_GET_S1(pcf) & LRB) {
350 		error = IIC_ENOACK;
351 		goto error;
352 	}
353 
354 	return (0);
355 
356 error:
357 	pcf_stop(pcfdev);
358 	return (error);
359 }
360 
361 void
362 pcfintr(unit)
363 {
364 	struct pcf_softc *pcf =
365 		(struct pcf_softc *)devclass_get_softc(pcf_devclass, unit);
366 
367 	char data, status, addr;
368 	char error = 0;
369 
370 	status = PCF_GET_S1(pcf);
371 
372 	if (status & PIN) {
373 		printf("pcf%d: spurious interrupt, status=0x%x\n", unit,
374 			status & 0xff);
375 
376 		goto error;
377 	}
378 
379 	if (status & LAB)
380 		printf("pcf%d: bus arbitration lost!\n", unit);
381 
382 	if (status & BER) {
383 		error = IIC_EBUSERR;
384 		iicbus_intr(pcf->iicbus, INTR_ERROR, &error);
385 
386 		goto error;
387 	}
388 
389 	do {
390 		status = PCF_GET_S1(pcf);
391 
392 		switch(pcf->pcf_slave_mode) {
393 
394 		case SLAVE_TRANSMITTER:
395 			if (status & LRB) {
396 				/* ack interrupt line */
397 				dummy_write(pcf);
398 
399 				/* no ack, don't send anymore */
400 				pcf->pcf_slave_mode = SLAVE_RECEIVER;
401 
402 				iicbus_intr(pcf->iicbus, INTR_NOACK, NULL);
403 				break;
404 			}
405 
406 			/* get data from upper code */
407 			iicbus_intr(pcf->iicbus, INTR_TRANSMIT, &data);
408 
409 			PCF_SET_S0(pcf, data);
410 			break;
411 
412 		case SLAVE_RECEIVER:
413 			if (status & AAS) {
414 				addr = PCF_GET_S0(pcf);
415 
416 				if (status & AD0)
417 					iicbus_intr(pcf->iicbus, INTR_GENERAL, &addr);
418 				else
419 					iicbus_intr(pcf->iicbus, INTR_START, &addr);
420 
421 				if (addr & LSB) {
422 					pcf->pcf_slave_mode = SLAVE_TRANSMITTER;
423 
424 					/* get the first char from upper code */
425 					iicbus_intr(pcf->iicbus, INTR_TRANSMIT, &data);
426 
427 					/* send first data byte */
428 					PCF_SET_S0(pcf, data);
429 				}
430 
431 				break;
432 			}
433 
434 			/* stop condition received? */
435 			if (status & STS) {
436 				/* ack interrupt line */
437 				dummy_read(pcf);
438 
439 				/* emulate intr stop condition */
440 				iicbus_intr(pcf->iicbus, INTR_STOP, NULL);
441 
442 			} else {
443 				/* get data, ack interrupt line */
444 				data = PCF_GET_S0(pcf);
445 
446 				/* deliver the character */
447 				iicbus_intr(pcf->iicbus, INTR_RECEIVE, &data);
448 			}
449 			break;
450 
451 		    default:
452 			panic("%s: unknown slave mode (%d)!", __FUNCTION__,
453 				pcf->pcf_slave_mode);
454 		    }
455 
456 	} while ((PCF_GET_S1(pcf) & PIN) == 0);
457 
458 	return;
459 
460 error:
461 	/* unknown event on bus...reset PCF */
462 	PCF_SET_S1(pcf, PIN|ES0|ENI|ACK);
463 
464 	pcf->pcf_slave_mode = SLAVE_RECEIVER;
465 
466 	return;
467 }
468 
469 static int pcf_rst_card(device_t pcfdev, u_char speed)
470 {
471 	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
472 	u_char ownaddr;
473 
474 	/* retrieve own address from bus level */
475 	if ((ownaddr = iicbus_get_own_address(pcf->iicbus)) == 0)
476 		ownaddr = 0xaa;
477 
478 	PCF_SET_S1(pcf, PIN);				/* initialize S1 */
479 
480 	/* own address S'O<>0 */
481 	PCF_SET_S0(pcf, ownaddr >> 1);
482 
483 	/* select clock register */
484 	PCF_SET_S1(pcf, PIN|ES1);
485 
486 	/* select bus speed : 18=90kb, 19=45kb, 1A=11kb, 1B=1.5kb */
487 	switch (speed) {
488 	case IIC_SLOW:
489 		PCF_SET_S0(pcf,  0x1b);
490 		break;
491 
492 	case IIC_FAST:
493 		PCF_SET_S0(pcf,  0x19);
494 		break;
495 
496 	case IIC_UNKNOWN:
497 	case IIC_FASTEST:
498 	default:
499 		PCF_SET_S0(pcf,  0x18);
500 		break;
501 	}
502 
503 	/* set bus on, ack=yes, INT=yes */
504 	PCF_SET_S1(pcf, PIN|ES0|ENI|ACK);
505 
506 	pcf->pcf_slave_mode = SLAVE_RECEIVER;
507 
508 	return (0);
509 }
510 
511 static int
512 pcf_write(device_t pcfdev, char *buf, int len, int *sent)
513 {
514 	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
515 	int bytes, error = 0;
516 
517 #ifdef PCFDEBUG
518 	printf("pcf%d: >> writing %d bytes\n", device_get_unit(pcfdev), len);
519 #endif
520 
521 	bytes = 0;
522 	while (len) {
523 
524 		PCF_SET_S0(pcf, *buf++);
525 
526 		if ((error = pcf_wait_byte(pcf)))
527 			goto error;
528 
529 		if (PCF_GET_S1(pcf) & LRB) {
530 			error = IIC_ENOACK;
531 			goto error;
532 		}
533 
534 		len --;
535 		bytes ++;
536 	}
537 
538 error:
539 	*sent = bytes;
540 
541 #ifdef PCFDEBUG
542 	printf("pcf%d: >> %d bytes written (%d)\n",
543 		device_get_unit(pcfdev), bytes, error);
544 #endif
545 
546 	return (error);
547 }
548 
549 static int
550 pcf_read(device_t pcfdev, char *buf, int len, int *read)
551 {
552 	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
553 	int bytes, error = 0;
554 
555 #ifdef PCFDEBUG
556 	printf("pcf%d: << reading %d bytes\n", device_get_unit(pcfdev), len);
557 #endif
558 
559 	/* trig the bus to get the first data byte in S0 */
560 	if (len) {
561 		if (len == 1)
562 			/* just one byte to read */
563 			PCF_SET_S1(pcf, ES0);		/* no ack */
564 
565 		dummy_read(pcf);
566 	}
567 
568 	bytes = 0;
569 	while (len) {
570 
571 		if ((error = pcf_wait_byte(pcf))) {
572 			pcf_stop(pcfdev);
573 			goto error;
574 		}
575 
576 		if (len == 1) {
577 
578 			/* ok, last data byte already in S0 */
579 			pcf_stop(pcfdev);
580 
581 			*buf = PCF_GET_S0(pcf);
582 
583 		} else {
584 			if (len == 2)
585 				/* next trigged byte with no ack */
586 				PCF_SET_S1(pcf, ES0);
587 
588 			/* read last data byte, trig for next data byte */
589 			*buf++ = PCF_GET_S0(pcf);
590 		}
591 
592 		len --;
593 		bytes ++;
594 	};
595 
596 error:
597 	*read = bytes;
598 
599 #ifdef PCFDEBUG
600 	printf("pcf%d: << %d bytes read (%d)\n",
601 		device_get_unit(pcfdev), bytes, error);
602 #endif
603 
604 	return (error);
605 }
606 
607 DRIVER_MODULE(pcf, root, pcf_driver, pcf_devclass, 0, 0);
608