1 /* $NetBSD: gpiic_opb.c,v 1.5 2007/12/06 17:00:33 ad Exp $ */
4 * Copyright 2002, 2003 Wasabi Systems, Inc.
7 * Written by Steve C. Woodford for Wasabi Systems, Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed for the NetBSD Project by
20 * Wasabi Systems, Inc.
21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22 * or promote products derived from this software without specific prior
25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/device.h>
43 #include <sys/errno.h>
44 #include <sys/mutex.h>
47 #include <dev/i2c/i2cvar.h>
48 #include <dev/i2c/i2c_bitbang.h>
50 #include <powerpc/ibm4xx/dev/opbvar.h>
51 #include <powerpc/ibm4xx/dev/gpiicreg.h>
55 bus_space_tag_t sc_bust
;
56 bus_space_handle_t sc_bush
;
59 struct i2c_controller sc_i2c
;
60 struct i2c_bitbang_ops sc_bops
;
64 static int gpiic_match(struct device
*, struct cfdata
*, void *);
65 static void gpiic_attach(struct device
*, struct device
*, void *);
67 CFATTACH_DECL(gpiic
, sizeof(struct gpiic_softc
),
68 gpiic_match
, gpiic_attach
, NULL
, NULL
);
70 static int gpiic_acquire_bus(void *, int);
71 static void gpiic_release_bus(void *, int);
72 static int gpiic_send_start(void *, int);
73 static int gpiic_send_stop(void *, int);
74 static int gpiic_initiate_xfer(void *, i2c_addr_t
, int);
75 static int gpiic_read_byte(void *, uint8_t *, int);
76 static int gpiic_write_byte(void *, uint8_t, int);
77 static void gpiic_set_dir(void *, uint32_t);
78 static void gpiic_set_bits(void *, uint32_t);
79 static uint32_t gpiic_read_bits(void *);
82 gpiic_match(struct device
*parent
, struct cfdata
*cf
, void *args
)
84 struct opb_attach_args
*oaa
= args
;
86 if (strcmp(oaa
->opb_name
, cf
->cf_name
) != 0)
93 gpiic_attach(struct device
*parent
, struct device
*self
, void *args
)
95 struct gpiic_softc
*sc
= (struct gpiic_softc
*)self
;
96 struct opb_attach_args
*oaa
= args
;
97 struct i2cbus_attach_args iba
;
99 aprint_naive(": IIC controller\n");
100 aprint_normal(": On-Chip IIC controller\n");
102 sc
->sc_bust
= oaa
->opb_bt
;
104 bus_space_map(sc
->sc_bust
, oaa
->opb_addr
, IIC_NREG
, 0, &sc
->sc_bush
);
106 mutex_init(&sc
->sc_buslock
, MUTEX_DEFAULT
, IPL_NONE
);
109 sc
->sc_tx
= IIC_DIRECTCNTL_SCC
| IIC_DIRECTCNTL_SDAC
;
110 sc
->sc_i2c
.ic_cookie
= sc
;
111 sc
->sc_i2c
.ic_acquire_bus
= gpiic_acquire_bus
;
112 sc
->sc_i2c
.ic_release_bus
= gpiic_release_bus
;
113 sc
->sc_i2c
.ic_exec
= NULL
;
114 sc
->sc_i2c
.ic_send_start
= gpiic_send_start
;
115 sc
->sc_i2c
.ic_send_stop
= gpiic_send_stop
;
116 sc
->sc_i2c
.ic_initiate_xfer
= gpiic_initiate_xfer
;
117 sc
->sc_i2c
.ic_read_byte
= gpiic_read_byte
;
118 sc
->sc_i2c
.ic_write_byte
= gpiic_write_byte
;
120 sc
->sc_bops
.ibo_set_dir
= gpiic_set_dir
;
121 sc
->sc_bops
.ibo_set_bits
= gpiic_set_bits
;
122 sc
->sc_bops
.ibo_read_bits
= gpiic_read_bits
;
123 sc
->sc_bops
.ibo_bits
[I2C_BIT_SDA
] = IIC_DIRECTCNTL_SDAC
;
124 sc
->sc_bops
.ibo_bits
[I2C_BIT_SCL
] = IIC_DIRECTCNTL_SCC
;
125 sc
->sc_bops
.ibo_bits
[I2C_BIT_OUTPUT
] = 1;
126 sc
->sc_bops
.ibo_bits
[I2C_BIT_INPUT
] = 0;
129 * Put the controller into Soft Reset. This allows us to
130 * manually bit-bang the I2C clock/data lines.
132 bus_space_write_1(sc
->sc_bust
, sc
->sc_bush
, IIC_XTCNTLSS
,
135 bus_space_write_1(sc
->sc_bust
, sc
->sc_bush
, IIC_DIRECTCNTL
,
136 IIC_DIRECTCNTL_SCC
| IIC_DIRECTCNTL_SDAC
);
138 iba
.iba_tag
= &sc
->sc_i2c
;
139 (void) config_found_ia(&sc
->sc_dev
, "i2cbus", &iba
, iicbus_print
);
143 gpiic_acquire_bus(void *arg
, int flags
)
145 struct gpiic_softc
*sc
= arg
;
147 if (flags
& I2C_F_POLL
)
150 mutex_enter(&sc
->sc_buslock
);
155 gpiic_release_bus(void *arg
, int flags
)
157 struct gpiic_softc
*sc
= arg
;
159 if (flags
& I2C_F_POLL
)
162 mutex_exit(&sc
->sc_buslock
);
166 gpiic_send_start(void *arg
, int flags
)
168 struct gpiic_softc
*sc
= arg
;
170 return (i2c_bitbang_send_start(sc
, flags
, &sc
->sc_bops
));
174 gpiic_send_stop(void *arg
, int flags
)
176 struct gpiic_softc
*sc
= arg
;
178 return (i2c_bitbang_send_stop(sc
, flags
, &sc
->sc_bops
));
182 gpiic_initiate_xfer(void *arg
, i2c_addr_t addr
, int flags
)
184 struct gpiic_softc
*sc
= arg
;
186 return (i2c_bitbang_initiate_xfer(sc
, addr
, flags
, &sc
->sc_bops
));
190 gpiic_read_byte(void *arg
, uint8_t *vp
, int flags
)
192 struct gpiic_softc
*sc
= arg
;
194 return (i2c_bitbang_read_byte(sc
, vp
, flags
, &sc
->sc_bops
));
198 gpiic_write_byte(void *arg
, uint8_t v
, int flags
)
200 struct gpiic_softc
*sc
= arg
;
202 return (i2c_bitbang_write_byte(sc
, v
, flags
, &sc
->sc_bops
));
206 gpiic_set_dir(void *arg
, uint32_t bits
)
208 struct gpiic_softc
*sc
= arg
;
211 txen
= (uint8_t)bits
;
212 if (sc
->sc_txen
== txen
)
218 if (sc
->sc_txen
== 0)
219 tx
|= IIC_DIRECTCNTL_SDAC
;
220 bus_space_write_1(sc
->sc_bust
, sc
->sc_bush
, IIC_DIRECTCNTL
, tx
);
224 gpiic_set_bits(void *arg
, uint32_t bits
)
226 struct gpiic_softc
*sc
= arg
;
228 sc
->sc_tx
= (uint8_t)bits
;
229 if (sc
->sc_txen
== 0)
230 bits
|= IIC_DIRECTCNTL_SDAC
;
232 bus_space_write_1(sc
->sc_bust
, sc
->sc_bush
, IIC_DIRECTCNTL
, bits
);
236 gpiic_read_bits(void *arg
)
238 struct gpiic_softc
*sc
= arg
;
241 rv
= bus_space_read_1(sc
->sc_bust
, sc
->sc_bush
, IIC_DIRECTCNTL
) << 2;
242 rv
&= (IIC_DIRECTCNTL_SCC
| IIC_DIRECTCNTL_SDAC
);
244 return ((uint32_t)rv
);