1129704Sjoerg/*-
2129704Sjoerg * Copyright (c) 1998 Nicolas Souchu, Marc Bouget
3129704Sjoerg * Copyright (c) 2004 Joerg Wunsch
4129704Sjoerg * All rights reserved.
5129704Sjoerg *
6129704Sjoerg * Redistribution and use in source and binary forms, with or without
7129704Sjoerg * modification, are permitted provided that the following conditions
8129704Sjoerg * are met:
9129704Sjoerg * 1. Redistributions of source code must retain the above copyright
10129704Sjoerg *    notice, this list of conditions and the following disclaimer.
11129704Sjoerg * 2. Redistributions in binary form must reproduce the above copyright
12129704Sjoerg *    notice, this list of conditions and the following disclaimer in the
13129704Sjoerg *    documentation and/or other materials provided with the distribution.
14129704Sjoerg *
15129704Sjoerg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16129704Sjoerg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17129704Sjoerg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18129704Sjoerg * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19129704Sjoerg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20129704Sjoerg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21129704Sjoerg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22129704Sjoerg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23129704Sjoerg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24129704Sjoerg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25129704Sjoerg * SUCH DAMAGE.
26129704Sjoerg *
27129704Sjoerg * $FreeBSD$
28129704Sjoerg */
29129704Sjoerg
30181303Sjhb#ifndef __PCFVAR_H__
31181303Sjhb#define	__PCFVAR_H__
32181303Sjhb
33129704Sjoerg#define IO_PCFSIZE	2
34129704Sjoerg
35129704Sjoerg#define TIMEOUT	9999					/* XXX */
36129704Sjoerg
37129704Sjoerg/* Status bits of S1 register (read only) */
38129704Sjoerg#define nBB	0x01		/* busy when low set/reset by STOP/START*/
39129704Sjoerg#define LAB	0x02		/* lost arbitration bit in multi-master mode */
40129704Sjoerg#define AAS	0x04		/* addressed as slave */
41129704Sjoerg#define LRB	0x08		/* last received byte when not AAS */
42129704Sjoerg#define AD0	0x08		/* general call received when AAS */
43129704Sjoerg#define BER	0x10		/* bus error, misplaced START or STOP */
44129704Sjoerg#define STS	0x20		/* STOP detected in slave receiver mode */
45129704Sjoerg#define PIN	0x80		/* pending interrupt not (r/w) */
46129704Sjoerg
47129704Sjoerg/* Control bits of S1 register (write only) */
48129704Sjoerg#define ACK	0x01
49129704Sjoerg#define STO	0x02
50129704Sjoerg#define STA	0x04
51129704Sjoerg#define ENI	0x08
52129704Sjoerg#define ES2	0x10
53129704Sjoerg#define ES1	0x20
54129704Sjoerg#define ESO	0x40
55129704Sjoerg
56129704Sjoerg#define BUFSIZE 2048
57129704Sjoerg
58129704Sjoerg#define SLAVE_TRANSMITTER	0x1
59129704Sjoerg#define SLAVE_RECEIVER		0x2
60129704Sjoerg
61129704Sjoerg#define PCF_DEFAULT_ADDR	0xaa
62129704Sjoerg
63129704Sjoergstruct pcf_softc {
64129704Sjoerg	u_char	pcf_addr;		/* interface I2C address */
65129704Sjoerg	int	pcf_flags;		/* IIC_POLLED? */
66129704Sjoerg	int	pcf_slave_mode;		/* receiver or transmitter */
67129704Sjoerg	int	pcf_started;		/* 1 if start condition sent */
68129704Sjoerg
69181303Sjhb	struct mtx pcf_lock;
70129704Sjoerg	device_t iicbus;		/* the corresponding iicbus */
71129704Sjoerg
72129704Sjoerg	/* Resource handling stuff. */
73133522Smarius	struct resource		*res_ioport;
74133522Smarius	int			rid_ioport;
75133522Smarius	struct resource		*res_irq;
76133522Smarius	int			rid_irq;
77133522Smarius	void			*intr_cookie;
78129704Sjoerg};
79129704Sjoerg#define DEVTOSOFTC(dev) ((struct pcf_softc *)device_get_softc(dev))
80129704Sjoerg
81181303Sjhb#define	PCF_LOCK(sc)		mtx_lock(&(sc)->pcf_lock)
82181303Sjhb#define	PCF_UNLOCK(sc)		mtx_unlock(&(sc)->pcf_lock)
83181303Sjhb#define	PCF_ASSERT_LOCKED(sc)	mtx_assert(&(sc)->pcf_lock, MA_OWNED)
84181303Sjhb
85129704Sjoerg/*
86129704Sjoerg * PCF8584 datasheet : when operate at 8 MHz or more, a minimun time of
87129704Sjoerg * 6 clocks cycles must be left between two consecutives access
88129704Sjoerg */
89129704Sjoerg#define pcf_nops()	DELAY(10)
90129704Sjoerg
91129704Sjoerg#define dummy_read(sc)	pcf_get_S0(sc)
92129704Sjoerg#define dummy_write(sc)	pcf_set_S0(sc, 0)
93129704Sjoerg
94129704Sjoerg/*
95129704Sjoerg * Specific register access to PCF8584
96129704Sjoerg */
97131575Sstefanfstatic __inline void
98129704Sjoergpcf_set_S0(struct pcf_softc *sc, int data)
99129704Sjoerg{
100133522Smarius
101181303Sjhb	bus_write_1(sc->res_ioport, 0, data);
102129704Sjoerg	pcf_nops();
103129704Sjoerg}
104129704Sjoerg
105131575Sstefanfstatic __inline void
106129704Sjoergpcf_set_S1(struct pcf_softc *sc, int data)
107129704Sjoerg{
108133522Smarius
109181303Sjhb	bus_write_1(sc->res_ioport, 1, data);
110129704Sjoerg	pcf_nops();
111129704Sjoerg}
112129704Sjoerg
113131575Sstefanfstatic __inline char
114129704Sjoergpcf_get_S0(struct pcf_softc *sc)
115129704Sjoerg{
116129704Sjoerg	char data;
117129704Sjoerg
118181303Sjhb	data = bus_read_1(sc->res_ioport, 0);
119129704Sjoerg	pcf_nops();
120129704Sjoerg
121129704Sjoerg	return (data);
122129704Sjoerg}
123129704Sjoerg
124131575Sstefanfstatic __inline char
125129704Sjoergpcf_get_S1(struct pcf_softc *sc)
126129704Sjoerg{
127129704Sjoerg	char data;
128129704Sjoerg
129181303Sjhb	data = bus_read_1(sc->res_ioport, 1);
130129704Sjoerg	pcf_nops();
131129704Sjoerg
132129704Sjoerg	return (data);
133129704Sjoerg}
134129704Sjoerg
135129704Sjoergextern int pcf_repeated_start(device_t, u_char, int);
136129704Sjoergextern int pcf_start(device_t, u_char, int);
137129704Sjoergextern int pcf_stop(device_t);
138194026Savgextern int pcf_write(device_t, const char *, int, int *, int);
139129704Sjoergextern int pcf_read(device_t, char *, int, int *, int, int);
140129704Sjoergextern int pcf_rst_card(device_t, u_char, u_char, u_char *);
141129704Sjoergextern driver_intr_t pcf_intr;
142129704Sjoerg
143129704Sjoerg#define PCF_MODVER	1
144129704Sjoerg#define PCF_MINVER	1
145129704Sjoerg#define PCF_MAXVER	1
146129704Sjoerg#define PCF_PREFVER	PCF_MODVER
147181303Sjhb
148181303Sjhb#endif /* !__PCFVAR_H__ */
149