1 /* $NetBSD: pxa2x0_i2c.c,v 1.3 2007/10/17 19:53:44 garbled Exp $ */
2 /* $OpenBSD: pxa2x0_i2c.c,v 1.2 2005/05/26 03:52:07 pascoe Exp $ */
5 * Copyright (c) 2005 Christopher Pascoe <pascoe@openbsd.org>
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <sys/cdefs.h>
21 __KERNEL_RCSID(0, "$NetBSD: pxa2x0_i2c.c,v 1.3 2007/10/17 19:53:44 garbled Exp $");
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/device.h>
27 #include <machine/bus.h>
29 #include <arm/xscale/pxa2x0reg.h>
30 #include <arm/xscale/pxa2x0var.h>
31 #include <arm/xscale/pxa2x0_i2c.h>
32 #include <arm/xscale/pxa2x0_gpio.h>
34 #define I2C_RETRY_COUNT 10
37 pxa2x0_i2c_attach_sub(struct pxa2x0_i2c_softc
*sc
)
40 if (bus_space_map(sc
->sc_iot
, PXA2X0_I2C_BASE
,
41 PXA2X0_I2C_SIZE
, 0, &sc
->sc_ioh
)) {
45 bus_space_barrier(sc
->sc_iot
, sc
->sc_ioh
, 0, sc
->sc_size
,
46 BUS_SPACE_BARRIER_READ
|BUS_SPACE_BARRIER_WRITE
);
54 pxa2x0_i2c_detach_sub(struct pxa2x0_i2c_softc
*sc
)
58 bus_space_unmap(sc
->sc_iot
, sc
->sc_ioh
, sc
->sc_size
);
61 pxa2x0_clkman_config(CKEN_I2C
, 0);
67 pxa2x0_i2c_init(struct pxa2x0_i2c_softc
*sc
)
75 pxa2x0_i2c_open(struct pxa2x0_i2c_softc
*sc
)
78 /* Enable the clock to the standard I2C unit. */
79 pxa2x0_clkman_config(CKEN_I2C
, 1);
83 pxa2x0_i2c_close(struct pxa2x0_i2c_softc
*sc
)
86 /* Reset and disable the standard I2C unit. */
87 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, I2C_ICR
, ICR_UR
);
88 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, I2C_ISAR
, 0);
90 pxa2x0_clkman_config(CKEN_I2C
, 0);
94 pxa2x0_i2c_read(struct pxa2x0_i2c_softc
*sc
, u_char slave
, u_char
*valuep
)
96 bus_space_tag_t iot
= sc
->sc_iot
;
97 bus_space_handle_t ioh
= sc
->sc_ioh
;
99 int tries
= I2C_RETRY_COUNT
;
103 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_UR
);
104 bus_space_write_4(iot
, ioh
, I2C_ISAR
, 0x00);
105 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_ITE
| ISR_IRF
);
107 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_IUE
| ICR_SCLE
);
109 /* Write slave device address. */
110 bus_space_write_4(iot
, ioh
, I2C_IDBR
, (slave
<<1) | 0x1);
111 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
112 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
| ICR_START
);
113 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
114 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
& ~ICR_STOP
);
115 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
116 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
| ICR_TB
);
119 while ((bus_space_read_4(iot
, ioh
, I2C_ISR
) & ISR_ITE
) == 0) {
125 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_ITE
);
127 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
128 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
& ~ICR_START
);
130 /* Read data value. */
131 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
132 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
|
133 (ICR_STOP
| ICR_ACKNAK
));
134 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
135 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
| ICR_TB
);
138 while ((bus_space_read_4(iot
, ioh
, I2C_ISR
) & ISR_IRF
) == 0) {
144 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_IRF
);
146 rv
= bus_space_read_4(iot
, ioh
, I2C_IDBR
);
147 *valuep
= (u_char
)rv
;
148 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
149 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
& ~(ICR_STOP
| ICR_ACKNAK
));
157 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_UR
);
158 bus_space_write_4(iot
, ioh
, I2C_ISAR
, 0x00);
159 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_ITE
| ISR_IRF
);
160 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_IUE
| ICR_SCLE
);
166 pxa2x0_i2c_write(struct pxa2x0_i2c_softc
*sc
, u_char slave
, u_char value
)
168 bus_space_tag_t iot
= sc
->sc_iot
;
169 bus_space_handle_t ioh
= sc
->sc_ioh
;
171 int tries
= I2C_RETRY_COUNT
;
175 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_UR
);
176 bus_space_write_4(iot
, ioh
, I2C_ISAR
, 0x00);
177 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_ITE
);
179 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_IUE
| ICR_SCLE
);
181 /* Write slave device address. */
182 bus_space_write_4(iot
, ioh
, I2C_IDBR
, (slave
<<1));
183 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
184 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
| ICR_START
);
185 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
186 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
& ~ICR_STOP
);
187 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
188 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
| ICR_TB
);
191 while ((bus_space_read_4(iot
, ioh
, I2C_ISR
) & ISR_ITE
) == 0) {
196 if ((bus_space_read_4(iot
, ioh
, I2C_ISR
) & ISR_ACKNAK
) != 0)
199 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_ITE
);
202 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
203 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
& ~ICR_START
);
204 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
205 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
| ICR_STOP
);
206 bus_space_write_4(iot
, ioh
, I2C_IDBR
, value
);
207 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
208 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
| ICR_TB
);
211 while ((bus_space_read_4(iot
, ioh
, I2C_ISR
) & ISR_ITE
) == 0) {
216 if ((bus_space_read_4(iot
, ioh
, I2C_ISR
) & ISR_ACKNAK
) != 0)
219 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_ITE
);
221 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
222 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
& ~ICR_STOP
);
230 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_UR
);
231 bus_space_write_4(iot
, ioh
, I2C_ISAR
, 0x00);
232 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_ITE
);
233 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_IUE
| ICR_SCLE
);
239 * XXX The quick_{read,write} opertions are untested!
242 pxa2x0_i2c_quick(struct pxa2x0_i2c_softc
*sc
, u_char slave
, u_char rw
)
244 bus_space_tag_t iot
= sc
->sc_iot
;
245 bus_space_handle_t ioh
= sc
->sc_ioh
;
247 int tries
= I2C_RETRY_COUNT
;
251 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_UR
);
252 bus_space_write_4(iot
, ioh
, I2C_ISAR
, 0x00);
253 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_ITE
);
255 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_IUE
| ICR_SCLE
);
257 /* Write slave device address. */
258 bus_space_write_4(iot
, ioh
, I2C_IDBR
, (slave
<<1) | (rw
& 1));
259 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
260 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
| ICR_START
);
261 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
262 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
| ICR_STOP
);
263 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
266 while ((bus_space_read_4(iot
, ioh
, I2C_ISR
) & ISR_ITE
) == 0) {
271 if ((bus_space_read_4(iot
, ioh
, I2C_ISR
) & ISR_ACKNAK
) != 0)
274 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_ITE
);
276 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
277 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
& ~ICR_STOP
);
285 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_UR
);
286 bus_space_write_4(iot
, ioh
, I2C_ISAR
, 0x00);
287 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_ITE
);
288 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_IUE
| ICR_SCLE
);
294 pxa2x0_i2c_write_2(struct pxa2x0_i2c_softc
*sc
, u_char slave
, u_short value
)
296 bus_space_tag_t iot
= sc
->sc_iot
;
297 bus_space_handle_t ioh
= sc
->sc_ioh
;
299 int tries
= I2C_RETRY_COUNT
;
303 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_UR
);
304 bus_space_write_4(iot
, ioh
, I2C_ISAR
, 0x00);
305 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_ITE
);
307 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_IUE
| ICR_SCLE
);
309 /* Write slave device address. */
310 bus_space_write_4(iot
, ioh
, I2C_IDBR
, (slave
<<1));
311 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
312 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
| ICR_START
);
313 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
314 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
& ~ICR_STOP
);
315 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
316 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
| ICR_TB
);
319 while ((bus_space_read_4(iot
, ioh
, I2C_ISR
) & ISR_ITE
) == 0) {
324 if ((bus_space_read_4(iot
, ioh
, I2C_ISR
) & ISR_ACKNAK
) != 0)
327 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_ITE
);
329 /* Write upper 8 bits of data. */
330 bus_space_write_4(iot
, ioh
, I2C_IDBR
, (value
>> 8) & 0xff);
331 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
332 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
& ~ICR_START
);
333 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
334 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
& ~ICR_STOP
);
335 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
336 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
| ICR_TB
);
339 while ((bus_space_read_4(iot
, ioh
, I2C_ISR
) & ISR_ITE
) == 0) {
344 if ((bus_space_read_4(iot
, ioh
, I2C_ISR
) & ISR_ACKNAK
) != 0)
347 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_ITE
);
349 /* Write lower 8 bits of data. */
350 bus_space_write_4(iot
, ioh
, I2C_IDBR
, value
& 0xff);
351 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
352 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
& ~ICR_START
);
353 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
354 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
| ICR_STOP
);
355 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
356 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
| ICR_TB
);
359 while ((bus_space_read_4(iot
, ioh
, I2C_ISR
) & ISR_ITE
) == 0) {
364 if ((bus_space_read_4(iot
, ioh
, I2C_ISR
) & ISR_ACKNAK
) != 0)
367 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_ITE
);
369 rv
= bus_space_read_4(iot
, ioh
, I2C_ICR
);
370 bus_space_write_4(iot
, ioh
, I2C_ICR
, rv
& ~ICR_STOP
);
378 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_UR
);
379 bus_space_write_4(iot
, ioh
, I2C_ISAR
, 0x00);
380 bus_space_write_4(iot
, ioh
, I2C_ISR
, ISR_ITE
);
381 bus_space_write_4(iot
, ioh
, I2C_ICR
, ICR_IUE
| ICR_SCLE
);