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