Home | History | Annotate | Line # | Download | only in xscale
pxa2x0_i2c.c revision 1.1
      1 /*	$NetBSD: pxa2x0_i2c.c,v 1.1 2006/12/17 16:03:33 peter 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 (at) 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.1 2006/12/17 16:03:33 peter 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 	/*
     49 	 * Configure the alternate functions.  The _IN is arbitrary, as the
     50 	 * direction is managed by the I2C unit when comms are in progress.
     51 	 */
     52 	pxa2x0_gpio_set_function(117, GPIO_ALT_FN_1_IN);	/* SCL */
     53 	pxa2x0_gpio_set_function(118, GPIO_ALT_FN_1_IN);	/* SDA */
     54 
     55 	pxa2x0_i2c_init(sc);
     56 
     57 	return 0;
     58 }
     59 
     60 int
     61 pxa2x0_i2c_detach_sub(struct pxa2x0_i2c_softc *sc)
     62 {
     63 
     64 	if (sc->sc_size) {
     65 		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
     66 		sc->sc_size = 0;
     67 	}
     68 	pxa2x0_clkman_config(CKEN_I2C, 0);
     69 
     70 	return 0;
     71 }
     72 
     73 void
     74 pxa2x0_i2c_init(struct pxa2x0_i2c_softc *sc)
     75 {
     76 
     77 	pxa2x0_i2c_open(sc);
     78 	pxa2x0_i2c_close(sc);
     79 }
     80 
     81 void
     82 pxa2x0_i2c_open(struct pxa2x0_i2c_softc *sc)
     83 {
     84 
     85 	/* Enable the clock to the standard I2C unit. */
     86 	pxa2x0_clkman_config(CKEN_I2C, 1);
     87 }
     88 
     89 void
     90 pxa2x0_i2c_close(struct pxa2x0_i2c_softc *sc)
     91 {
     92 
     93 	/* Reset and disable the standard I2C unit. */
     94 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, I2C_ICR, ICR_UR);
     95 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, I2C_ISAR, 0);
     96 	delay(1);
     97 	pxa2x0_clkman_config(CKEN_I2C, 0);
     98 }
     99 
    100 int
    101 pxa2x0_i2c_read(struct pxa2x0_i2c_softc *sc, u_char slave, u_char *valuep)
    102 {
    103 	bus_space_tag_t iot = sc->sc_iot;
    104 	bus_space_handle_t ioh = sc->sc_ioh;
    105 	int timeout;
    106 	int tries = I2C_RETRY_COUNT;
    107 	uint32_t rv;
    108 
    109 retry:
    110 	bus_space_write_4(iot, ioh, I2C_ICR, ICR_UR);
    111 	bus_space_write_4(iot, ioh, I2C_ISAR, 0x00);
    112 	bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE | ISR_IRF);
    113 	delay(1);
    114 	bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE);
    115 
    116 	/* Write slave device address. */
    117 	bus_space_write_4(iot, ioh, I2C_IDBR, (slave<<1) | 0x1);
    118 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    119 	bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_START);
    120 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    121 	bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP);
    122 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    123 	bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB);
    124 
    125 	timeout = 10000;
    126 	while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) {
    127 		if (timeout-- == 0)
    128 			goto err;
    129 		delay(1);
    130 	}
    131 
    132 	bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
    133 
    134 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    135 	bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_START);
    136 
    137 	/* Read data value. */
    138 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    139 	bus_space_write_4(iot, ioh, I2C_ICR, rv |
    140 	    (ICR_STOP | ICR_ACKNAK));
    141 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    142 	bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB);
    143 
    144 	timeout = 10000;
    145 	while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_IRF) == 0) {
    146 		if (timeout-- == 0)
    147 			goto err;
    148 		delay(1);
    149 	}
    150 
    151 	bus_space_write_4(iot, ioh, I2C_ISR, ISR_IRF);
    152 
    153 	rv = bus_space_read_4(iot, ioh, I2C_IDBR);
    154 	*valuep = (u_char)rv;
    155 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    156 	bus_space_write_4(iot, ioh, I2C_ICR, rv & ~(ICR_STOP | ICR_ACKNAK));
    157 
    158 	return 0;
    159 
    160 err:
    161 	if (tries-- >= 0)
    162 		goto retry;
    163 
    164 	bus_space_write_4(iot, ioh, I2C_ICR, ICR_UR);
    165 	bus_space_write_4(iot, ioh, I2C_ISAR, 0x00);
    166 	bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE | ISR_IRF);
    167 	bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE);
    168 
    169 	return EIO;
    170 }
    171 
    172 int
    173 pxa2x0_i2c_write(struct pxa2x0_i2c_softc *sc, u_char slave, u_char value)
    174 {
    175 	bus_space_tag_t iot = sc->sc_iot;
    176 	bus_space_handle_t ioh = sc->sc_ioh;
    177 	int timeout;
    178 	int tries = I2C_RETRY_COUNT;
    179 	uint32_t rv;
    180 
    181 retry:
    182 	bus_space_write_4(iot, ioh, I2C_ICR, ICR_UR);
    183 	bus_space_write_4(iot, ioh, I2C_ISAR, 0x00);
    184 	bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
    185 	delay(1);
    186 	bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE);
    187 
    188 	/* Write slave device address. */
    189 	bus_space_write_4(iot, ioh, I2C_IDBR, (slave<<1));
    190 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    191 	bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_START);
    192 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    193 	bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP);
    194 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    195 	bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB);
    196 
    197 	timeout = 10000;
    198 	while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) {
    199 		if (timeout-- == 0)
    200 			goto err;
    201 		delay(1);
    202 	}
    203 	if ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ACKNAK) != 0)
    204 		goto err;
    205 
    206 	bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
    207 
    208 	/* Write data. */
    209 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    210 	bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_START);
    211 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    212 	bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_STOP);
    213 	bus_space_write_4(iot, ioh, I2C_IDBR, value);
    214 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    215 	bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB);
    216 
    217 	timeout = 10000;
    218 	while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) {
    219 		if (timeout-- == 0)
    220 			goto err;
    221 		delay(1);
    222 	}
    223 	if ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ACKNAK) != 0)
    224 		goto err;
    225 
    226 	bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
    227 
    228 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    229 	bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP);
    230 
    231 	return 0;
    232 
    233 err:
    234 	if (tries-- >= 0)
    235 		goto retry;
    236 
    237 	bus_space_write_4(iot, ioh, I2C_ICR, ICR_UR);
    238 	bus_space_write_4(iot, ioh, I2C_ISAR, 0x00);
    239 	bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
    240 	bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE);
    241 
    242 	return EIO;
    243 }
    244 
    245 int
    246 pxa2x0_i2c_write_2(struct pxa2x0_i2c_softc *sc, u_char slave, u_short value)
    247 {
    248 	bus_space_tag_t iot = sc->sc_iot;
    249 	bus_space_handle_t ioh = sc->sc_ioh;
    250 	int timeout;
    251 	int tries = I2C_RETRY_COUNT;
    252 	uint32_t rv;
    253 
    254 retry:
    255 	bus_space_write_4(iot, ioh, I2C_ICR, ICR_UR);
    256 	bus_space_write_4(iot, ioh, I2C_ISAR, 0x00);
    257 	bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
    258 	delay(1);
    259 	bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE);
    260 
    261 	/* Write slave device address. */
    262 	bus_space_write_4(iot, ioh, I2C_IDBR, (slave<<1));
    263 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    264 	bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_START);
    265 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    266 	bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP);
    267 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    268 	bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB);
    269 
    270 	timeout = 10000;
    271 	while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) {
    272 		if (timeout-- == 0)
    273 			goto err;
    274 		delay(1);
    275 	}
    276 	if ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ACKNAK) != 0)
    277 		goto err;
    278 
    279 	bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
    280 
    281 	/* Write upper 8 bits of data. */
    282 	bus_space_write_4(iot, ioh, I2C_IDBR, (value >> 8) & 0xff);
    283 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    284 	bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_START);
    285 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    286 	bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP);
    287 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    288 	bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB);
    289 
    290 	timeout = 10000;
    291 	while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) {
    292 		if (timeout-- == 0)
    293 			goto err;
    294 		delay(1);
    295 	}
    296 	if ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ACKNAK) != 0)
    297 		goto err;
    298 
    299 	bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
    300 
    301 	/* Write lower 8 bits of data. */
    302 	bus_space_write_4(iot, ioh, I2C_IDBR, value & 0xff);
    303 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    304 	bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_START);
    305 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    306 	bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_STOP);
    307 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    308 	bus_space_write_4(iot, ioh, I2C_ICR, rv | ICR_TB);
    309 
    310 	timeout = 10000;
    311 	while ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ITE) == 0) {
    312 		if (timeout-- == 0)
    313 			goto err;
    314 		delay(1);
    315 	}
    316 	if ((bus_space_read_4(iot, ioh, I2C_ISR) & ISR_ACKNAK) != 0)
    317 		goto err;
    318 
    319 	bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
    320 
    321 	rv = bus_space_read_4(iot, ioh, I2C_ICR);
    322 	bus_space_write_4(iot, ioh, I2C_ICR, rv & ~ICR_STOP);
    323 
    324 	return 0;
    325 
    326 err:
    327 	if (tries-- >= 0)
    328 		goto retry;
    329 
    330 	bus_space_write_4(iot, ioh, I2C_ICR, ICR_UR);
    331 	bus_space_write_4(iot, ioh, I2C_ISAR, 0x00);
    332 	bus_space_write_4(iot, ioh, I2C_ISR, ISR_ITE);
    333 	bus_space_write_4(iot, ioh, I2C_ICR, ICR_IUE | ICR_SCLE);
    334 
    335 	return EIO;
    336 }
    337