pcf.c revision 129703
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
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/dev/pcf/pcf.c 126996 2004-03-14 23:03:57Z imp $");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/kernel.h>
33#include <sys/module.h>
34#include <sys/bus.h>
35
36#include <machine/bus.h>
37#include <machine/resource.h>
38#include <sys/rman.h>
39
40#include <isa/isareg.h>
41#include <isa/isavar.h>
42
43#include <dev/iicbus/iiconf.h>
44#include "iicbus_if.h"
45
46#define IO_PCFSIZE	2
47
48#define TIMEOUT	9999					/* XXX */
49
50/* Status bits of S1 register (read only) */
51#define nBB	0x01		/* busy when low set/reset by STOP/START*/
52#define LAB	0x02		/* lost arbitration bit in multi-master mode */
53#define AAS	0x04		/* addressed as slave */
54#define LRB	0x08		/* last received byte when not AAS */
55#define AD0	0x08		/* general call received when AAS */
56#define BER	0x10		/* bus error, misplaced START or STOP */
57#define STS	0x20		/* STOP detected in slave receiver mode */
58#define PIN	0x80		/* pending interrupt not (r/w) */
59
60/* Control bits of S1 register (write only) */
61#define ACK	0x01
62#define STO	0x02
63#define STA	0x04
64#define ENI	0x08
65#define ES2	0x10
66#define ES1	0x20
67#define ES0	0x40
68
69#define BUFSIZE 2048
70
71#define SLAVE_TRANSMITTER	0x1
72#define SLAVE_RECEIVER		0x2
73
74#define PCF_DEFAULT_ADDR	0xaa
75
76struct pcf_softc {
77
78	int pcf_base;			/* isa port */
79	int pcf_flags;
80	u_char pcf_addr;		/* interface I2C address */
81
82	int pcf_slave_mode;		/* receiver or transmitter */
83	int pcf_started;		/* 1 if start condition sent */
84
85	device_t iicbus;		/* the corresponding iicbus */
86
87  	int rid_irq, rid_ioport;
88	struct resource *res_irq, *res_ioport;
89	void *intr_cookie;
90};
91
92static int pcf_probe(device_t);
93static int pcf_attach(device_t);
94static void pcfintr(void *arg);
95
96static int pcf_print_child(device_t, device_t);
97
98static int pcf_repeated_start(device_t, u_char, int);
99static int pcf_start(device_t, u_char, int);
100static int pcf_stop(device_t);
101static int pcf_write(device_t, char *, int, int *, int);
102static int pcf_read(device_t, char *, int, int *, int, int);
103static int pcf_rst_card(device_t, u_char, u_char, u_char *);
104
105static device_method_t pcf_methods[] = {
106	/* device interface */
107	DEVMETHOD(device_probe,		pcf_probe),
108	DEVMETHOD(device_attach,	pcf_attach),
109
110	/* bus interface */
111	DEVMETHOD(bus_print_child,	pcf_print_child),
112
113	/* iicbus interface */
114	DEVMETHOD(iicbus_callback,	iicbus_null_callback),
115	DEVMETHOD(iicbus_repeated_start, pcf_repeated_start),
116	DEVMETHOD(iicbus_start,		pcf_start),
117	DEVMETHOD(iicbus_stop,		pcf_stop),
118	DEVMETHOD(iicbus_write,		pcf_write),
119	DEVMETHOD(iicbus_read,		pcf_read),
120	DEVMETHOD(iicbus_reset,		pcf_rst_card),
121
122	{ 0, 0 }
123};
124
125static driver_t pcf_driver = {
126	"pcf",
127	pcf_methods,
128	sizeof(struct pcf_softc),
129};
130
131static devclass_t pcf_devclass;
132
133#define DEVTOSOFTC(dev) ((struct pcf_softc *)device_get_softc(dev))
134
135static int
136pcf_probe(device_t pcfdev)
137{
138	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
139	device_t parent = device_get_parent(pcfdev);
140	uintptr_t base;
141
142	device_set_desc(pcfdev, "PCF8584 I2C bus controller");
143
144	pcf = DEVTOSOFTC(pcfdev);
145	bzero(pcf, sizeof(struct pcf_softc));
146
147	pcf->rid_irq = pcf->rid_ioport = 0;
148	pcf->res_irq = pcf->res_ioport = 0;
149
150	/* IO port is mandatory */
151	pcf->res_ioport = bus_alloc_resource(pcfdev, SYS_RES_IOPORT,
152					     &pcf->rid_ioport, 0ul, ~0ul,
153					     IO_PCFSIZE, RF_ACTIVE);
154	if (pcf->res_ioport == 0) {
155		device_printf(pcfdev, "cannot reserve I/O port range\n");
156		goto error;
157	}
158	BUS_READ_IVAR(parent, pcfdev, ISA_IVAR_PORT, &base);
159	pcf->pcf_base = base;
160
161	pcf->pcf_flags = device_get_flags(pcfdev);
162
163	if (!(pcf->pcf_flags & IIC_POLLED)) {
164		pcf->res_irq = bus_alloc_resource(pcfdev, SYS_RES_IRQ, &pcf->rid_irq,
165						  0ul, ~0ul, 1, RF_ACTIVE);
166		if (pcf->res_irq == 0) {
167			device_printf(pcfdev, "can't reserve irq, polled mode.\n");
168			pcf->pcf_flags |= IIC_POLLED;
169		}
170	}
171
172	/* reset the chip */
173	pcf_rst_card(pcfdev, IIC_FASTEST, PCF_DEFAULT_ADDR, NULL);
174
175	return (0);
176error:
177	if (pcf->res_ioport != 0) {
178		bus_deactivate_resource(pcfdev, SYS_RES_IOPORT, pcf->rid_ioport,
179					pcf->res_ioport);
180		bus_release_resource(pcfdev, SYS_RES_IOPORT, pcf->rid_ioport,
181				     pcf->res_ioport);
182	}
183	return (ENXIO);
184}
185
186static int
187pcf_attach(device_t pcfdev)
188{
189	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
190	device_t parent = device_get_parent(pcfdev);
191	int error = 0;
192
193	if (pcf->res_irq) {
194		/* default to the tty mask for registration */	/* XXX */
195		error = BUS_SETUP_INTR(parent, pcfdev, pcf->res_irq, INTR_TYPE_NET,
196					    pcfintr, pcfdev, &pcf->intr_cookie);
197		if (error)
198			return (error);
199	}
200
201	pcf->iicbus = device_add_child(pcfdev, "iicbus", -1);
202
203	/* probe and attach the iicbus */
204	bus_generic_attach(pcfdev);
205
206	return (0);
207}
208
209static int
210pcf_print_child(device_t bus, device_t dev)
211{
212	struct pcf_softc *pcf = (struct pcf_softc *)device_get_softc(bus);
213	int retval = 0;
214
215	retval += bus_print_child_header(bus, dev);
216	retval += printf(" on %s addr 0x%x\n", device_get_nameunit(bus),
217			 (int)pcf->pcf_addr);
218
219	return (retval);
220}
221
222/*
223 * PCF8584 datasheet : when operate at 8 MHz or more, a minimun time of
224 * 6 clocks cycles must be left between two consecutives access
225 */
226#define pcf_nops()	DELAY(10)
227
228#define dummy_read(pcf)		PCF_GET_S0(pcf)
229#define dummy_write(pcf)	PCF_SET_S0(pcf, 0)
230
231/*
232 * Specific register access to PCF8584
233 */
234static void PCF_SET_S0(struct pcf_softc *pcf, int data)
235{
236	outb(pcf->pcf_base, data);
237	pcf_nops();
238}
239
240static void PCF_SET_S1(struct pcf_softc *pcf, int data)
241{
242	outb(pcf->pcf_base+1, data);
243	pcf_nops();
244}
245
246static char PCF_GET_S0(struct pcf_softc *pcf)
247{
248	char data;
249
250	data = inb(pcf->pcf_base);
251	pcf_nops();
252
253	return (data);
254}
255
256static char PCF_GET_S1(struct pcf_softc *pcf)
257{
258	char data;
259
260	data = inb(pcf->pcf_base+1);
261	pcf_nops();
262
263	return (data);
264}
265
266/*
267 * Polling mode for master operations wait for a new
268 * byte incomming or outgoing
269 */
270static int pcf_wait_byte(struct pcf_softc *pcf)
271{
272	int counter = TIMEOUT;
273
274	while (counter--) {
275
276		if ((PCF_GET_S1(pcf) & PIN) == 0)
277			return (0);
278	}
279
280	return (IIC_ETIMEOUT);
281}
282
283static int pcf_stop(device_t pcfdev)
284{
285	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
286
287	/*
288	 * Send STOP condition iff the START condition was previously sent.
289	 * STOP is sent only once even if an iicbus_stop() is called after
290	 * an iicbus_read()... see pcf_read(): the pcf needs to send the stop
291	 * before the last char is read.
292	 */
293	if (pcf->pcf_started) {
294		/* set stop condition and enable IT */
295		PCF_SET_S1(pcf, PIN|ES0|ENI|STO|ACK);
296
297		pcf->pcf_started = 0;
298	}
299
300	return (0);
301}
302
303
304static int pcf_noack(struct pcf_softc *pcf, int timeout)
305{
306	int noack;
307	int k = timeout/10;
308
309	do {
310		noack = PCF_GET_S1(pcf) & LRB;
311		if (!noack)
312			break;
313		DELAY(10);				/* XXX wait 10 us */
314	} while (k--);
315
316	return (noack);
317}
318
319static int pcf_repeated_start(device_t pcfdev, u_char slave, int timeout)
320{
321	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
322	int error = 0;
323
324	/* repeated start */
325	PCF_SET_S1(pcf, ES0|STA|STO|ACK);
326
327	/* set slave address to PCF. Last bit (LSB) must be set correctly
328	 * according to transfer direction */
329	PCF_SET_S0(pcf, slave);
330
331	/* wait for address sent, polling */
332	if ((error = pcf_wait_byte(pcf)))
333		goto error;
334
335	/* check for ack */
336	if (pcf_noack(pcf, timeout)) {
337		error = IIC_ENOACK;
338		goto error;
339	}
340
341	return (0);
342
343error:
344	pcf_stop(pcfdev);
345	return (error);
346}
347
348static int pcf_start(device_t pcfdev, u_char slave, int timeout)
349{
350	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
351	int error = 0;
352
353	if ((PCF_GET_S1(pcf) & nBB) == 0)
354		return (IIC_EBUSBSY);
355
356	/* set slave address to PCF. Last bit (LSB) must be set correctly
357	 * according to transfer direction */
358	PCF_SET_S0(pcf, slave);
359
360	/* START only */
361	PCF_SET_S1(pcf, PIN|ES0|STA|ACK);
362
363	pcf->pcf_started = 1;
364
365	/* wait for address sent, polling */
366	if ((error = pcf_wait_byte(pcf)))
367		goto error;
368
369	/* check for ACK */
370	if (pcf_noack(pcf, timeout)) {
371		error = IIC_ENOACK;
372		goto error;
373	}
374
375	return (0);
376
377error:
378	pcf_stop(pcfdev);
379	return (error);
380}
381
382static void
383pcfintr(void *arg)
384{
385	device_t pcfdev = (device_t)arg;
386	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
387
388	char data, status, addr;
389	char error = 0;
390
391	status = PCF_GET_S1(pcf);
392
393	if (status & PIN) {
394		device_printf(pcfdev, "spurious interrupt, status=0x%x\n", status & 0xff);
395
396		goto error;
397	}
398
399	if (status & LAB)
400		device_printf(pcfdev, "bus arbitration lost!\n");
401
402	if (status & BER) {
403		error = IIC_EBUSERR;
404		iicbus_intr(pcf->iicbus, INTR_ERROR, &error);
405
406		goto error;
407	}
408
409	do {
410		status = PCF_GET_S1(pcf);
411
412		switch(pcf->pcf_slave_mode) {
413
414		case SLAVE_TRANSMITTER:
415			if (status & LRB) {
416				/* ack interrupt line */
417				dummy_write(pcf);
418
419				/* no ack, don't send anymore */
420				pcf->pcf_slave_mode = SLAVE_RECEIVER;
421
422				iicbus_intr(pcf->iicbus, INTR_NOACK, NULL);
423				break;
424			}
425
426			/* get data from upper code */
427			iicbus_intr(pcf->iicbus, INTR_TRANSMIT, &data);
428
429			PCF_SET_S0(pcf, data);
430			break;
431
432		case SLAVE_RECEIVER:
433			if (status & AAS) {
434				addr = PCF_GET_S0(pcf);
435
436				if (status & AD0)
437					iicbus_intr(pcf->iicbus, INTR_GENERAL, &addr);
438				else
439					iicbus_intr(pcf->iicbus, INTR_START, &addr);
440
441				if (addr & LSB) {
442					pcf->pcf_slave_mode = SLAVE_TRANSMITTER;
443
444					/* get the first char from upper code */
445					iicbus_intr(pcf->iicbus, INTR_TRANSMIT, &data);
446
447					/* send first data byte */
448					PCF_SET_S0(pcf, data);
449				}
450
451				break;
452			}
453
454			/* stop condition received? */
455			if (status & STS) {
456				/* ack interrupt line */
457				dummy_read(pcf);
458
459				/* emulate intr stop condition */
460				iicbus_intr(pcf->iicbus, INTR_STOP, NULL);
461
462			} else {
463				/* get data, ack interrupt line */
464				data = PCF_GET_S0(pcf);
465
466				/* deliver the character */
467				iicbus_intr(pcf->iicbus, INTR_RECEIVE, &data);
468			}
469			break;
470
471		    default:
472			panic("%s: unknown slave mode (%d)!", __func__,
473				pcf->pcf_slave_mode);
474		    }
475
476	} while ((PCF_GET_S1(pcf) & PIN) == 0);
477
478	return;
479
480error:
481	/* unknown event on bus...reset PCF */
482	PCF_SET_S1(pcf, PIN|ES0|ENI|ACK);
483
484	pcf->pcf_slave_mode = SLAVE_RECEIVER;
485
486	return;
487}
488
489static int pcf_rst_card(device_t pcfdev, u_char speed, u_char addr, u_char *oldaddr)
490{
491	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
492
493	if (oldaddr)
494		*oldaddr = pcf->pcf_addr;
495
496	/* retrieve own address from bus level */
497	if (!addr)
498		pcf->pcf_addr = PCF_DEFAULT_ADDR;
499	else
500		pcf->pcf_addr = addr;
501
502	PCF_SET_S1(pcf, PIN);				/* initialize S1 */
503
504	/* own address S'O<>0 */
505	PCF_SET_S0(pcf, pcf->pcf_addr >> 1);
506
507	/* select clock register */
508	PCF_SET_S1(pcf, PIN|ES1);
509
510	/* select bus speed : 18=90kb, 19=45kb, 1A=11kb, 1B=1.5kb */
511	switch (speed) {
512	case IIC_SLOW:
513		PCF_SET_S0(pcf,  0x1b);
514		break;
515
516	case IIC_FAST:
517		PCF_SET_S0(pcf,  0x19);
518		break;
519
520	case IIC_UNKNOWN:
521	case IIC_FASTEST:
522	default:
523		PCF_SET_S0(pcf,  0x18);
524		break;
525	}
526
527	/* set bus on, ack=yes, INT=yes */
528	PCF_SET_S1(pcf, PIN|ES0|ENI|ACK);
529
530	pcf->pcf_slave_mode = SLAVE_RECEIVER;
531
532	return (0);
533}
534
535static int
536pcf_write(device_t pcfdev, char *buf, int len, int *sent, int timeout /* us */)
537{
538	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
539	int bytes, error = 0;
540
541#ifdef PCFDEBUG
542	printf("pcf%d: >> writing %d bytes\n", device_get_unit(pcfdev), len);
543#endif
544
545	bytes = 0;
546	while (len) {
547
548		PCF_SET_S0(pcf, *buf++);
549
550		/* wait for the byte to be send */
551		if ((error = pcf_wait_byte(pcf)))
552			goto error;
553
554		/* check if ack received */
555		if (pcf_noack(pcf, timeout)) {
556			error = IIC_ENOACK;
557			goto error;
558		}
559
560		len --;
561		bytes ++;
562	}
563
564error:
565	*sent = bytes;
566
567#ifdef PCFDEBUG
568	printf("pcf%d: >> %d bytes written (%d)\n",
569		device_get_unit(pcfdev), bytes, error);
570#endif
571
572	return (error);
573}
574
575static int
576pcf_read(device_t pcfdev, char *buf, int len, int *read, int last,
577							int delay /* us */)
578{
579	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
580	int bytes, error = 0;
581
582#ifdef PCFDEBUG
583	printf("pcf%d: << reading %d bytes\n", device_get_unit(pcfdev), len);
584#endif
585
586	/* trig the bus to get the first data byte in S0 */
587	if (len) {
588		if (len == 1 && last)
589			/* just one byte to read */
590			PCF_SET_S1(pcf, ES0);		/* no ack */
591
592		dummy_read(pcf);
593	}
594
595	bytes = 0;
596	while (len) {
597
598		/* XXX delay needed here */
599
600		/* wait for trigged byte */
601		if ((error = pcf_wait_byte(pcf))) {
602			pcf_stop(pcfdev);
603			goto error;
604		}
605
606		if (len == 1 && last)
607			/* ok, last data byte already in S0, no I2C activity
608			 * on next PCF_GET_S0() */
609			pcf_stop(pcfdev);
610
611		else if (len == 2 && last)
612			/* next trigged byte with no ack */
613			PCF_SET_S1(pcf, ES0);
614
615		/* receive byte, trig next byte */
616		*buf++ = PCF_GET_S0(pcf);
617
618		len --;
619		bytes ++;
620	};
621
622error:
623	*read = bytes;
624
625#ifdef PCFDEBUG
626	printf("pcf%d: << %d bytes read (%d)\n",
627		device_get_unit(pcfdev), bytes, error);
628#endif
629
630	return (error);
631}
632
633DRIVER_MODULE(pcf, isa, pcf_driver, pcf_devclass, 0, 0);
634