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 $ */ 3 4 /* 5 * Copyright (c) 2005 Christopher Pascoe <pascoe@openbsd.org> 6 * 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. 10 * 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. 18 */ 19 20 #include <sys/cdefs.h> 21 __KERNEL_RCSID(0, "$NetBSD: pxa2x0_i2c.c,v 1.3 2007/10/17 19:53:44 garbled Exp $"); 22 23 #include <sys/param.h> 24 #include <sys/systm.h> 25 #include <sys/device.h> 26 27 #include <machine/bus.h> 28 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> 33 34 #define I2C_RETRY_COUNT 10 35 36 int 37 pxa2x0_i2c_attach_sub(struct pxa2x0_i2c_softc *sc) 38 { 39 40 if (bus_space_map(sc->sc_iot, PXA2X0_I2C_BASE, 41 PXA2X0_I2C_SIZE, 0, &sc->sc_ioh)) { 42 sc->sc_size = 0; 43 return EIO; 44 } 45 bus_space_barrier(sc->sc_iot, sc->sc_ioh, 0, sc->sc_size, 46 BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE); 47 48 pxa2x0_i2c_init(sc); 49 50 return 0; 51 } 52 53 int 54 pxa2x0_i2c_detach_sub(struct pxa2x0_i2c_softc *sc) 55 { 56 57 if (sc->sc_size) { 58 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size); 59 sc->sc_size = 0; 60 } 61 pxa2x0_clkman_config(CKEN_I2C, 0); 62 63 return 0; 64 } 65 66 void 67 pxa2x0_i2c_init(struct pxa2x0_i2c_softc *sc) 68 { 69 70 pxa2x0_i2c_open(sc); 71 pxa2x0_i2c_close(sc); 72 } 73 74 void 75 pxa2x0_i2c_open(struct pxa2x0_i2c_softc *sc) 76 { 77 78 /* Enable the clock to the standard I2C unit. */ 79 pxa2x0_clkman_config(CKEN_I2C, 1); 80 } 81 82 void 83 pxa2x0_i2c_close(struct pxa2x0_i2c_softc *sc) 84 { 85 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); 89 delay(1); 90 pxa2x0_clkman_config(CKEN_I2C, 0); 91 } 92 93 int 94 pxa2x0_i2c_read(struct pxa2x0_i2c_softc *sc, u_char slave, u_char *valuep) 95 { 96 bus_space_tag_t iot = sc->sc_iot; 97 bus_space_handle_t ioh = sc->sc_ioh; 98 int timeout; 99 int tries = I2C_RETRY_COUNT; 100 uint32_t rv; 101 102 retry: 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); 106 delay(1); 107 bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE); 108 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); 117 118 timeout = 10000; 119 while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) { 120 if (timeout-- == 0) 121 goto err; 122 delay(1); 123 } 124 125 bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE); 126 127 rv = bus_space_read_4(iot, ioh, I2C_ICR); 128 bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_START); 129 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); 136 137 timeout = 10000; 138 while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_IRF) == 0) { 139 if (timeout-- == 0) 140 goto err; 141 delay(1); 142 } 143 144 bus_space_write_4(iot, ioh, I2C_ISR, ISR_IRF); 145 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)); 150 151 return 0; 152 153 err: 154 if (tries-- >= 0) 155 goto retry; 156 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); 161 162 return EIO; 163 } 164 165 int 166 pxa2x0_i2c_write(struct pxa2x0_i2c_softc *sc, u_char slave, u_char value) 167 { 168 bus_space_tag_t iot = sc->sc_iot; 169 bus_space_handle_t ioh = sc->sc_ioh; 170 int timeout; 171 int tries = I2C_RETRY_COUNT; 172 uint32_t rv; 173 174 retry: 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); 178 delay(1); 179 bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE); 180 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); 189 190 timeout = 10000; 191 while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) { 192 if (timeout-- == 0) 193 goto err; 194 delay(1); 195 } 196 if ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ACKNAK) != 0) 197 goto err; 198 199 bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE); 200 201 /* Write data. */ 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); 209 210 timeout = 10000; 211 while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) { 212 if (timeout-- == 0) 213 goto err; 214 delay(1); 215 } 216 if ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ACKNAK) != 0) 217 goto err; 218 219 bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE); 220 221 rv = bus_space_read_4(iot, ioh, I2C_ICR); 222 bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP); 223 224 return 0; 225 226 err: 227 if (tries-- >= 0) 228 goto retry; 229 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); 234 235 return EIO; 236 } 237 238 int 239 pxa2x0_i2c_write_2(struct pxa2x0_i2c_softc *sc, u_char slave, u_short value) 240 { 241 bus_space_tag_t iot = sc->sc_iot; 242 bus_space_handle_t ioh = sc->sc_ioh; 243 int timeout; 244 int tries = I2C_RETRY_COUNT; 245 uint32_t rv; 246 247 retry: 248 bus_space_write_4(iot, ioh, I2C_ICR, ICR_UR); 249 bus_space_write_4(iot, ioh, I2C_ISAR, 0x00); 250 bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE); 251 delay(1); 252 bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE); 253 254 /* Write slave device address. */ 255 bus_space_write_4(iot, ioh, I2C_IDBR, (slave<<1)); 256 rv = bus_space_read_4(iot, ioh, I2C_ICR); 257 bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_START); 258 rv = bus_space_read_4(iot, ioh, I2C_ICR); 259 bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP); 260 rv = bus_space_read_4(iot, ioh, I2C_ICR); 261 bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB); 262 263 timeout = 10000; 264 while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) { 265 if (timeout-- == 0) 266 goto err; 267 delay(1); 268 } 269 if ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ACKNAK) != 0) 270 goto err; 271 272 bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE); 273 274 /* Write upper 8 bits of data. */ 275 bus_space_write_4(iot, ioh, I2C_IDBR, (value >> 8) & 0xff); 276 rv = bus_space_read_4(iot, ioh, I2C_ICR); 277 bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_START); 278 rv = bus_space_read_4(iot, ioh, I2C_ICR); 279 bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP); 280 rv = bus_space_read_4(iot, ioh, I2C_ICR); 281 bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB); 282 283 timeout = 10000; 284 while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) { 285 if (timeout-- == 0) 286 goto err; 287 delay(1); 288 } 289 if ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ACKNAK) != 0) 290 goto err; 291 292 bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE); 293 294 /* Write lower 8 bits of data. */ 295 bus_space_write_4(iot, ioh, I2C_IDBR, value & 0xff); 296 rv = bus_space_read_4(iot, ioh, I2C_ICR); 297 bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_START); 298 rv = bus_space_read_4(iot, ioh, I2C_ICR); 299 bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_STOP); 300 rv = bus_space_read_4(iot, ioh, I2C_ICR); 301 bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB); 302 303 timeout = 10000; 304 while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) { 305 if (timeout-- == 0) 306 goto err; 307 delay(1); 308 } 309 if ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ACKNAK) != 0) 310 goto err; 311 312 bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE); 313 314 rv = bus_space_read_4(iot, ioh, I2C_ICR); 315 bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP); 316 317 return 0; 318 319 err: 320 if (tries-- >= 0) 321 goto retry; 322 323 bus_space_write_4(iot, ioh, I2C_ICR, ICR_UR); 324 bus_space_write_4(iot, ioh, I2C_ISAR, 0x00); 325 bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE); 326 bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE); 327 328 return EIO; 329 } 330