1 /* $OpenBSD: kiic.c,v 1.4 2013/10/09 17:53:29 mpi Exp $ */ 2 /* $NetBSD: kiic.c,v 1.1 2003/12/27 02:19:34 grant Exp $ */ 3 4 /*- 5 * Copyright (c) 2001 Tsubai Masanari. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <sys/param.h> 31 #include <sys/device.h> 32 #include <sys/systm.h> 33 34 #include <dev/ofw/openfirm.h> 35 #include <uvm/uvm_extern.h> 36 #include <machine/autoconf.h> 37 38 #include <macppc/dev/kiicvar.h> 39 #include <macppc/dev/maci2cvar.h> 40 41 int kiic_match(struct device *, void *, void *); 42 void kiic_attach(struct device *, struct device *, void *); 43 inline u_int kiic_readreg(struct kiic_softc *, int); 44 inline void kiic_writereg(struct kiic_softc *, int, u_int); 45 void kiic_setmode(struct kiic_softc *, u_int, u_int); 46 void kiic_setspeed(struct kiic_softc *, u_int); 47 int kiic_intr(struct kiic_softc *); 48 int kiic_poll(struct kiic_softc *, int); 49 int kiic_start(struct kiic_softc *, int, int, void *, int); 50 int kiic_read(struct kiic_softc *, int, int, void *, int); 51 int kiic_write(struct kiic_softc *, int, int, const void *, int); 52 53 /* I2C glue */ 54 int kiic_i2c_acquire_bus(void *, int); 55 void kiic_i2c_release_bus(void *, int); 56 int kiic_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t, 57 void *, size_t, int); 58 59 struct cfattach kiic_ca = { 60 sizeof(struct kiic_softc), kiic_match, kiic_attach 61 }; 62 struct cfattach kiic_memc_ca = { 63 sizeof(struct kiic_softc), kiic_match, kiic_attach 64 }; 65 66 struct cfdriver kiic_cd = { 67 NULL, "kiic", DV_DULL 68 }; 69 70 int 71 kiic_match(struct device *parent, void *match, void *aux) 72 { 73 struct confargs *ca = aux; 74 75 if (strcmp(ca->ca_name, "i2c") == 0 && 76 ca->ca_nreg >= 4) 77 return (1); 78 79 return (0); 80 } 81 82 void 83 kiic_attach(struct device *parent, struct device *self, void *aux) 84 { 85 struct kiic_softc *sc = (struct kiic_softc *)self; 86 struct confargs *ca = aux; 87 struct i2cbus_attach_args iba; 88 int rate, node = ca->ca_node; 89 char name[32]; 90 uint32_t reg; 91 92 ca->ca_reg[0] += ca->ca_baseaddr; 93 94 if (OF_getprop(node, "AAPL,i2c-rate", &rate, 4) != 4) { 95 printf(": cannot get i2c-rate\n"); 96 return; 97 } 98 if (OF_getprop(node, "AAPL,address", &sc->sc_paddr, 4) != 4) { 99 printf(": unable to find i2c address\n"); 100 return; 101 } 102 if (OF_getprop(node, "AAPL,address-step", &sc->sc_regstep, 4) != 4) { 103 printf(": unable to find i2c address step\n"); 104 return; 105 } 106 sc->sc_reg = mapiodev(sc->sc_paddr, (DATA+1)*sc->sc_regstep); 107 108 printf("\n"); 109 110 kiic_writereg(sc, STATUS, 0); 111 kiic_writereg(sc, ISR, 0); 112 kiic_writereg(sc, IER, 0); 113 114 kiic_setmode(sc, I2C_STDSUBMODE, 0); 115 kiic_setspeed(sc, I2C_100kHz); /* XXX rate */ 116 117 rw_init(&sc->sc_buslock, sc->sc_dev.dv_xname); 118 kiic_writereg(sc, IER,I2C_INT_DATA|I2C_INT_ADDR|I2C_INT_STOP); 119 120 sc->sc_busnode = node; 121 122 node = OF_child(ca->ca_node); 123 if (OF_getprop(node, "name", name, sizeof(name)) > 0) { 124 if (strcmp(name, "i2c-bus") == 0) { 125 if (OF_getprop(node, "reg", ®, sizeof(reg)) > 0) 126 sc->sc_busport = reg; 127 128 sc->sc_busnode = node; 129 } 130 } 131 132 sc->sc_i2c_tag.ic_cookie = sc; 133 sc->sc_i2c_tag.ic_acquire_bus = kiic_i2c_acquire_bus; 134 sc->sc_i2c_tag.ic_release_bus = kiic_i2c_release_bus; 135 sc->sc_i2c_tag.ic_exec = kiic_i2c_exec; 136 137 bzero(&iba, sizeof(iba)); 138 iba.iba_name = "iic"; 139 iba.iba_tag = &sc->sc_i2c_tag; 140 iba.iba_bus_scan = maciic_scan; 141 iba.iba_bus_scan_arg = &sc->sc_busnode; 142 config_found(&sc->sc_dev, &iba, NULL); 143 } 144 145 u_int 146 kiic_readreg(struct kiic_softc *sc, int reg) 147 { 148 u_char *addr = sc->sc_reg + sc->sc_regstep * reg; 149 150 return (*addr); 151 } 152 153 void 154 kiic_writereg(struct kiic_softc *sc, int reg, u_int val) 155 { 156 u_char *addr = sc->sc_reg + sc->sc_regstep * reg; 157 158 *addr = val; 159 asm volatile ("eieio"); 160 delay(10); 161 } 162 163 void 164 kiic_setmode(struct kiic_softc *sc, u_int mode, u_int bus) 165 { 166 u_int x; 167 168 KASSERT((mode & ~I2C_MODE) == 0); 169 x = kiic_readreg(sc, MODE); 170 x &= ~(I2C_MODE); 171 if (bus) 172 x |= I2C_BUS1; 173 else 174 x &= ~I2C_BUS1; 175 x |= mode; 176 kiic_writereg(sc, MODE, x); 177 } 178 179 void 180 kiic_setspeed(struct kiic_softc *sc, u_int speed) 181 { 182 u_int x; 183 184 KASSERT((speed & ~I2C_SPEED) == 0); 185 x = kiic_readreg(sc, MODE); 186 x &= ~I2C_SPEED; 187 x |= speed; 188 kiic_writereg(sc, MODE, x); 189 } 190 191 int 192 kiic_intr(struct kiic_softc *sc) 193 { 194 u_int isr, x; 195 196 isr = kiic_readreg(sc, ISR); 197 if (isr & I2C_INT_ADDR) { 198 #if 0 199 if ((kiic_readreg(sc, STATUS) & I2C_ST_LASTAAK) == 0) { 200 /* No slave responded. */ 201 sc->sc_flags |= I2C_ERROR; 202 goto out; 203 } 204 #endif 205 206 if (sc->sc_flags & I2C_READING) { 207 if (sc->sc_resid > 1) { 208 x = kiic_readreg(sc, CONTROL); 209 x |= I2C_CT_AAK; 210 kiic_writereg(sc, CONTROL, x); 211 } 212 } else { 213 kiic_writereg(sc, DATA, *sc->sc_data++); 214 sc->sc_resid--; 215 } 216 } 217 218 if (isr & I2C_INT_DATA) { 219 if (sc->sc_flags & I2C_READING) { 220 if (sc->sc_resid > 0) { 221 *sc->sc_data++ = kiic_readreg(sc, DATA); 222 sc->sc_resid--; 223 } 224 if (sc->sc_resid == 0) { /* Completed */ 225 kiic_writereg(sc, CONTROL, 0); 226 goto out; 227 } 228 } else { 229 #if 0 230 if ((kiic_readreg(sc, STATUS) & I2C_ST_LASTAAK) == 0) { 231 /* No slave responded. */ 232 sc->sc_flags |= I2C_ERROR; 233 goto out; 234 } 235 #endif 236 237 if (sc->sc_resid == 0) { 238 x = kiic_readreg(sc, CONTROL) | I2C_CT_STOP; 239 kiic_writereg(sc, CONTROL, x); 240 } else { 241 kiic_writereg(sc, DATA, *sc->sc_data++); 242 sc->sc_resid--; 243 } 244 } 245 } 246 247 out: 248 if (isr & I2C_INT_STOP) { 249 kiic_writereg(sc, CONTROL, 0); 250 sc->sc_flags &= ~I2C_BUSY; 251 } 252 253 kiic_writereg(sc, ISR, isr); 254 255 return (1); 256 } 257 258 int 259 kiic_poll(struct kiic_softc *sc, int timo) 260 { 261 while (sc->sc_flags & I2C_BUSY) { 262 if (kiic_readreg(sc, ISR)) 263 kiic_intr(sc); 264 timo -= 100; 265 if (timo < 0) { 266 printf("i2c_poll: timeout\n"); 267 return (-1); 268 } 269 delay(100); 270 } 271 return (0); 272 } 273 274 int 275 kiic_start(struct kiic_softc *sc, int addr, int subaddr, void *data, int len) 276 { 277 int rw = (sc->sc_flags & I2C_READING) ? 1 : 0; 278 int timo, x; 279 280 KASSERT((addr & 1) == 0); 281 282 sc->sc_data = data; 283 sc->sc_resid = len; 284 sc->sc_flags |= I2C_BUSY; 285 286 timo = 1000 + len * 200; 287 288 /* XXX TAS3001 sometimes takes 50ms to finish writing registers. */ 289 /* if (addr == 0x68) */ 290 timo += 100000; 291 292 kiic_writereg(sc, ADDR, addr | rw); 293 kiic_writereg(sc, SUBADDR, subaddr); 294 295 x = kiic_readreg(sc, CONTROL) | I2C_CT_ADDR; 296 kiic_writereg(sc, CONTROL, x); 297 298 if (kiic_poll(sc, timo)) 299 return (-1); 300 if (sc->sc_flags & I2C_ERROR) { 301 printf("I2C_ERROR\n"); 302 return (-1); 303 } 304 if (sc->sc_resid != 0) 305 return (-1); 306 return (0); 307 } 308 309 int 310 kiic_read(struct kiic_softc *sc, int addr, int subaddr, void *data, int len) 311 { 312 sc->sc_flags = I2C_READING; 313 return kiic_start(sc, addr, subaddr, data, len); 314 } 315 316 int 317 kiic_write(struct kiic_softc *sc, int addr, int subaddr, const void *data, int len) 318 { 319 sc->sc_flags = 0; 320 return kiic_start(sc, addr, subaddr, (void *)data, len); 321 } 322 323 int 324 kiic_i2c_acquire_bus(void *cookie, int flags) 325 { 326 struct kiic_softc *sc = cookie; 327 328 return (rw_enter(&sc->sc_buslock, RW_WRITE)); 329 } 330 331 void 332 kiic_i2c_release_bus(void *cookie, int flags) 333 { 334 struct kiic_softc *sc = cookie; 335 336 (void) rw_exit(&sc->sc_buslock); 337 } 338 339 int 340 kiic_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, 341 const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags) 342 { 343 struct kiic_softc *sc = cookie; 344 u_int mode = I2C_STDSUBMODE; 345 u_int8_t cmd = 0; 346 347 if (!I2C_OP_STOP_P(op) || cmdlen > 1) 348 return (EINVAL); 349 350 if (cmdlen == 0) 351 mode = I2C_STDMODE; 352 else if (I2C_OP_READ_P(op)) 353 mode = I2C_COMBMODE; 354 355 if (cmdlen > 0) 356 cmd = *(u_int8_t *)cmdbuf; 357 358 /* 359 * Use the value read from the "i2c-bus" child node or 360 * the 9th bit of the address to select the right bus. 361 */ 362 kiic_setmode(sc, mode, sc->sc_busport || addr & 0x80); 363 addr &= 0x7f; 364 365 if (I2C_OP_READ_P(op)) { 366 if (kiic_read(sc, (addr << 1), cmd, buf, len) != 0) 367 return (EIO); 368 } else { 369 if (kiic_write(sc, (addr << 1), cmd, buf, len) != 0) 370 return (EIO); 371 } 372 return (0); 373 } 374