pcfvar.h revision 129704
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 * $FreeBSD: head/sys/dev/pcf/pcfvar.h 129704 2004-05-25 07:42:45Z joerg $
28 */
29
30#define IO_PCFSIZE	2
31
32#define TIMEOUT	9999					/* XXX */
33
34/* Status bits of S1 register (read only) */
35#define nBB	0x01		/* busy when low set/reset by STOP/START*/
36#define LAB	0x02		/* lost arbitration bit in multi-master mode */
37#define AAS	0x04		/* addressed as slave */
38#define LRB	0x08		/* last received byte when not AAS */
39#define AD0	0x08		/* general call received when AAS */
40#define BER	0x10		/* bus error, misplaced START or STOP */
41#define STS	0x20		/* STOP detected in slave receiver mode */
42#define PIN	0x80		/* pending interrupt not (r/w) */
43
44/* Control bits of S1 register (write only) */
45#define ACK	0x01
46#define STO	0x02
47#define STA	0x04
48#define ENI	0x08
49#define ES2	0x10
50#define ES1	0x20
51#define ESO	0x40
52
53#define BUFSIZE 2048
54
55#define SLAVE_TRANSMITTER	0x1
56#define SLAVE_RECEIVER		0x2
57
58#define PCF_DEFAULT_ADDR	0xaa
59
60struct pcf_softc {
61	u_char	pcf_addr;		/* interface I2C address */
62	int	pcf_flags;		/* IIC_POLLED? */
63	int	pcf_slave_mode;		/* receiver or transmitter */
64	int	pcf_started;		/* 1 if start condition sent */
65
66	device_t iicbus;		/* the corresponding iicbus */
67
68	/* Resource handling stuff. */
69	void	*intr_cookie;
70	int	rid_ioport;
71	int	rid_irq;
72	struct resource *res_ioport;
73	struct resource *res_irq;
74};
75#define DEVTOSOFTC(dev) ((struct pcf_softc *)device_get_softc(dev))
76
77/*
78 * PCF8584 datasheet : when operate at 8 MHz or more, a minimun time of
79 * 6 clocks cycles must be left between two consecutives access
80 */
81#define pcf_nops()	DELAY(10)
82
83#define dummy_read(sc)	pcf_get_S0(sc)
84#define dummy_write(sc)	pcf_set_S0(sc, 0)
85
86/*
87 * Specific register access to PCF8584
88 */
89static __inline__ void
90pcf_set_S0(struct pcf_softc *sc, int data)
91{
92	bus_space_write_1(sc->res_ioport->r_bustag,
93			  sc->res_ioport->r_bushandle,
94			  0, data);
95	pcf_nops();
96}
97
98static __inline__ void
99pcf_set_S1(struct pcf_softc *sc, int data)
100{
101	bus_space_write_1(sc->res_ioport->r_bustag,
102			  sc->res_ioport->r_bushandle,
103			  1, data);
104	pcf_nops();
105}
106
107static __inline__ char
108pcf_get_S0(struct pcf_softc *sc)
109{
110	char data;
111
112	data = bus_space_read_1(sc->res_ioport->r_bustag,
113				sc->res_ioport->r_bushandle, 0);
114	pcf_nops();
115
116	return (data);
117}
118
119static __inline__ char
120pcf_get_S1(struct pcf_softc *sc)
121{
122	char data;
123
124	data = bus_space_read_1(sc->res_ioport->r_bustag,
125				sc->res_ioport->r_bushandle, 1);
126	pcf_nops();
127
128	return (data);
129}
130
131extern int pcf_repeated_start(device_t, u_char, int);
132extern int pcf_start(device_t, u_char, int);
133extern int pcf_stop(device_t);
134extern int pcf_write(device_t, char *, int, int *, int);
135extern int pcf_read(device_t, char *, int, int *, int, int);
136extern int pcf_rst_card(device_t, u_char, u_char, u_char *);
137extern driver_intr_t pcf_intr;
138
139#define PCF_MODVER	1
140#define PCF_MINVER	1
141#define PCF_MAXVER	1
142#define PCF_PREFVER	PCF_MODVER
143