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