1 /* $OpenBSD: kiic.c,v 1.3 2008/04/18 17:59:37 deraadt 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 void kiic_attach_bus(struct kiic_softc *, struct kiic_bus *, int); 44 inline u_int kiic_readreg(struct kiic_softc *, int); 45 inline void kiic_writereg(struct kiic_softc *, int, u_int); 46 u_int kiic_getmode(struct kiic_softc *); 47 void kiic_setmode(struct kiic_softc *, u_int, u_int); 48 u_int kiic_getspeed(struct kiic_softc *); 49 void kiic_setspeed(struct kiic_softc *, u_int); 50 int kiic_intr(struct kiic_softc *); 51 int kiic_poll(struct kiic_softc *, int); 52 int kiic_start(struct kiic_softc *, int, int, void *, int); 53 int kiic_read(struct kiic_softc *, int, int, void *, int); 54 int kiic_write(struct kiic_softc *, int, int, const void *, int); 55 56 /* I2C glue */ 57 int kiic_i2c_acquire_bus(void *, int); 58 void kiic_i2c_release_bus(void *, int); 59 int kiic_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t, 60 void *, size_t, int); 61 62 struct cfattach kiic_ca = { 63 sizeof(struct kiic_softc), kiic_match, kiic_attach 64 }; 65 struct cfattach kiic_memc_ca = { 66 sizeof(struct kiic_softc), kiic_match, kiic_attach 67 }; 68 69 struct cfdriver kiic_cd = { 70 NULL, "kiic", DV_DULL 71 }; 72 73 int 74 kiic_match(struct device *parent, void *match, void *aux) 75 { 76 struct confargs *ca = aux; 77 78 if (strcmp(ca->ca_name, "i2c") == 0 && 79 ca->ca_nreg >= 4) 80 return (1); 81 82 return (0); 83 } 84 85 void 86 kiic_attach(struct device *parent, struct device *self, void *aux) 87 { 88 struct kiic_softc *sc = (struct kiic_softc *)self; 89 struct confargs *ca = aux; 90 int node = ca->ca_node; 91 int rate, count = 0; 92 char name[32]; 93 94 ca->ca_reg[0] += ca->ca_baseaddr; 95 96 if (OF_getprop(node, "AAPL,i2c-rate", &rate, 4) != 4) { 97 printf(": cannot get i2c-rate\n"); 98 return; 99 } 100 if (OF_getprop(node, "AAPL,address", &sc->sc_paddr, 4) != 4) { 101 printf(": unable to find i2c address\n"); 102 return; 103 } 104 if (OF_getprop(node, "AAPL,address-step", &sc->sc_regstep, 4) != 4) { 105 printf(": unable to find i2c address step\n"); 106 return; 107 } 108 sc->sc_reg = mapiodev(sc->sc_paddr, (DATA+1)*sc->sc_regstep); 109 110 printf("\n"); 111 112 kiic_writereg(sc, STATUS, 0); 113 kiic_writereg(sc, ISR, 0); 114 kiic_writereg(sc, IER, 0); 115 116 kiic_setmode(sc, I2C_STDSUBMODE, 0); 117 kiic_setspeed(sc, I2C_100kHz); /* XXX rate */ 118 119 rw_init(&sc->sc_buslock, sc->sc_dev.dv_xname); 120 kiic_writereg(sc, IER,I2C_INT_DATA|I2C_INT_ADDR|I2C_INT_STOP); 121 122 for (node = OF_child(ca->ca_node); node; node = OF_peer(node)) { 123 if (OF_getprop(node, "name", &name, sizeof name) > 0) { 124 if (strcmp(name, "i2c-bus") == 0) { 125 kiic_attach_bus(sc, &sc->sc_bus[count], node); 126 if (++count >= KIIC_MAX_BUSSES) 127 break; 128 } 129 } 130 } 131 132 /* 133 * If we didn't find any i2c-bus nodes, there is only a single 134 * i2c bus. 135 */ 136 137 if (count == 0) 138 kiic_attach_bus(sc, &sc->sc_bus[0], ca->ca_node); 139 } 140 141 void 142 kiic_attach_bus(struct kiic_softc *sc, struct kiic_bus *bus, int node) 143 { 144 struct i2cbus_attach_args iba; 145 u_int32_t reg; 146 147 if (OF_getprop(node, "reg", ®, sizeof reg) != sizeof reg) 148 return; 149 150 bus->sc = sc; 151 bus->i2c_tag.ic_cookie = bus; 152 bus->i2c_tag.ic_acquire_bus = kiic_i2c_acquire_bus; 153 bus->i2c_tag.ic_release_bus = kiic_i2c_release_bus; 154 bus->i2c_tag.ic_exec = kiic_i2c_exec; 155 bus->reg = reg; 156 157 bzero(&iba, sizeof iba); 158 iba.iba_name = "iic"; 159 iba.iba_tag = &bus->i2c_tag; 160 iba.iba_bus_scan = maciic_scan; 161 iba.iba_bus_scan_arg = &node; 162 config_found(&sc->sc_dev, &iba, NULL); 163 } 164 165 u_int 166 kiic_readreg(struct kiic_softc *sc, int reg) 167 { 168 u_char *addr = sc->sc_reg + sc->sc_regstep * reg; 169 170 return (*addr); 171 } 172 173 void 174 kiic_writereg(struct kiic_softc *sc, int reg, u_int val) 175 { 176 u_char *addr = sc->sc_reg + sc->sc_regstep * reg; 177 178 *addr = val; 179 asm volatile ("eieio"); 180 delay(10); 181 } 182 183 u_int 184 kiic_getmode(struct kiic_softc *sc) 185 { 186 return kiic_readreg(sc, MODE) & I2C_MODE; 187 } 188 189 void 190 kiic_setmode(struct kiic_softc *sc, u_int mode, u_int bus) 191 { 192 u_int x; 193 194 KASSERT((mode & ~I2C_MODE) == 0); 195 x = kiic_readreg(sc, MODE); 196 x &= ~(I2C_MODE); 197 if (bus) 198 x |= I2C_BUS1; 199 else 200 x &= ~I2C_BUS1; 201 x |= mode; 202 kiic_writereg(sc, MODE, x); 203 } 204 205 u_int 206 kiic_getspeed(struct kiic_softc *sc) 207 { 208 return kiic_readreg(sc, MODE) & I2C_SPEED; 209 } 210 211 void 212 kiic_setspeed(struct kiic_softc *sc, u_int speed) 213 { 214 u_int x; 215 216 KASSERT((speed & ~I2C_SPEED) == 0); 217 x = kiic_readreg(sc, MODE); 218 x &= ~I2C_SPEED; 219 x |= speed; 220 kiic_writereg(sc, MODE, x); 221 } 222 223 int 224 kiic_intr(struct kiic_softc *sc) 225 { 226 u_int isr, x; 227 228 isr = kiic_readreg(sc, ISR); 229 if (isr & I2C_INT_ADDR) { 230 #if 0 231 if ((kiic_readreg(sc, STATUS) & I2C_ST_LASTAAK) == 0) { 232 /* No slave responded. */ 233 sc->sc_flags |= I2C_ERROR; 234 goto out; 235 } 236 #endif 237 238 if (sc->sc_flags & I2C_READING) { 239 if (sc->sc_resid > 1) { 240 x = kiic_readreg(sc, CONTROL); 241 x |= I2C_CT_AAK; 242 kiic_writereg(sc, CONTROL, x); 243 } 244 } else { 245 kiic_writereg(sc, DATA, *sc->sc_data++); 246 sc->sc_resid--; 247 } 248 } 249 250 if (isr & I2C_INT_DATA) { 251 if (sc->sc_flags & I2C_READING) { 252 *sc->sc_data++ = kiic_readreg(sc, DATA); 253 sc->sc_resid--; 254 255 if (sc->sc_resid == 0) { /* Completed */ 256 kiic_writereg(sc, CONTROL, 0); 257 goto out; 258 } 259 } else { 260 #if 0 261 if ((kiic_readreg(sc, STATUS) & I2C_ST_LASTAAK) == 0) { 262 /* No slave responded. */ 263 sc->sc_flags |= I2C_ERROR; 264 goto out; 265 } 266 #endif 267 268 if (sc->sc_resid == 0) { 269 x = kiic_readreg(sc, CONTROL) | I2C_CT_STOP; 270 kiic_writereg(sc, CONTROL, x); 271 } else { 272 kiic_writereg(sc, DATA, *sc->sc_data++); 273 sc->sc_resid--; 274 } 275 } 276 } 277 278 out: 279 if (isr & I2C_INT_STOP) { 280 kiic_writereg(sc, CONTROL, 0); 281 sc->sc_flags &= ~I2C_BUSY; 282 } 283 284 kiic_writereg(sc, ISR, isr); 285 286 return (1); 287 } 288 289 int 290 kiic_poll(struct kiic_softc *sc, int timo) 291 { 292 while (sc->sc_flags & I2C_BUSY) { 293 if (kiic_readreg(sc, ISR)) 294 kiic_intr(sc); 295 timo -= 100; 296 if (timo < 0) { 297 printf("i2c_poll: timeout\n"); 298 return (-1); 299 } 300 delay(100); 301 } 302 return (0); 303 } 304 305 int 306 kiic_start(struct kiic_softc *sc, int addr, int subaddr, void *data, int len) 307 { 308 int rw = (sc->sc_flags & I2C_READING) ? 1 : 0; 309 int timo, x; 310 311 KASSERT((addr & 1) == 0); 312 313 sc->sc_data = data; 314 sc->sc_resid = len; 315 sc->sc_flags |= I2C_BUSY; 316 317 timo = 1000 + len * 200; 318 319 /* XXX TAS3001 sometimes takes 50ms to finish writing registers. */ 320 /* if (addr == 0x68) */ 321 timo += 100000; 322 323 kiic_writereg(sc, ADDR, addr | rw); 324 kiic_writereg(sc, SUBADDR, subaddr); 325 326 x = kiic_readreg(sc, CONTROL) | I2C_CT_ADDR; 327 kiic_writereg(sc, CONTROL, x); 328 329 if (kiic_poll(sc, timo)) 330 return (-1); 331 if (sc->sc_flags & I2C_ERROR) { 332 printf("I2C_ERROR\n"); 333 return (-1); 334 } 335 if (sc->sc_resid != 0) 336 return (-1); 337 return (0); 338 } 339 340 int 341 kiic_read(struct kiic_softc *sc, int addr, int subaddr, void *data, int len) 342 { 343 sc->sc_flags = I2C_READING; 344 return kiic_start(sc, addr, subaddr, data, len); 345 } 346 347 int 348 kiic_write(struct kiic_softc *sc, int addr, int subaddr, const void *data, int len) 349 { 350 sc->sc_flags = 0; 351 return kiic_start(sc, addr, subaddr, (void *)data, len); 352 } 353 354 int 355 kiic_i2c_acquire_bus(void *cookie, int flags) 356 { 357 struct kiic_bus *bus = cookie; 358 359 return (rw_enter(&bus->sc->sc_buslock, RW_WRITE)); 360 } 361 362 void 363 kiic_i2c_release_bus(void *cookie, int flags) 364 { 365 struct kiic_bus *bus = cookie; 366 367 (void) rw_exit(&bus->sc->sc_buslock); 368 } 369 370 int 371 kiic_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, 372 const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags) 373 { 374 struct kiic_bus *bus = cookie; 375 u_int mode = I2C_STDSUBMODE; 376 u_int8_t cmd = 0; 377 378 if (!I2C_OP_STOP_P(op) || cmdlen > 1) 379 return (EINVAL); 380 381 if (cmdlen == 0) 382 mode = I2C_STDMODE; 383 else if (I2C_OP_READ_P(op)) 384 mode = I2C_COMBMODE; 385 386 if (cmdlen > 0) 387 cmd = *(u_int8_t *)cmdbuf; 388 389 kiic_setmode(bus->sc, mode, bus->reg || addr & 0x80); 390 addr &= 0x7f; 391 392 if (I2C_OP_READ_P(op)) { 393 if (kiic_read(bus->sc, (addr << 1), cmd, buf, len) != 0) 394 return (EIO); 395 } else { 396 if (kiic_write(bus->sc, (addr << 1), cmd, buf, len) != 0) 397 return (EIO); 398 } 399 return (0); 400 } 401