1/* $NetBSD: ki2c.c,v 1.33 2022/06/29 17:59:40 mlelstv Exp $ */ 2/* Id: ki2c.c,v 1.7 2002/10/05 09:56:05 tsubai 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#include <sys/mutex.h> 34 35#include <dev/ofw/openfirm.h> 36#include <machine/autoconf.h> 37 38#include "opt_ki2c.h" 39#include <macppc/dev/ki2cvar.h> 40 41#ifdef KI2C_DEBUG 42#define DPRINTF printf 43#else 44#define DPRINTF while (0) printf 45#endif 46 47#define KI2C_EXEC_MAX_CMDLEN 32 48#define KI2C_EXEC_MAX_BUFLEN 32 49 50int ki2c_match(device_t, cfdata_t, void *); 51void ki2c_attach(device_t, device_t, void *); 52inline uint8_t ki2c_readreg(struct ki2c_softc *, int); 53inline void ki2c_writereg(struct ki2c_softc *, int, uint8_t); 54u_int ki2c_getmode(struct ki2c_softc *); 55void ki2c_setmode(struct ki2c_softc *, u_int); 56u_int ki2c_getspeed(struct ki2c_softc *); 57void ki2c_setspeed(struct ki2c_softc *, u_int); 58int ki2c_intr(struct ki2c_softc *); 59int ki2c_poll(struct ki2c_softc *, int); 60int ki2c_start(struct ki2c_softc *, int, int, void *, int); 61int ki2c_read(struct ki2c_softc *, int, int, void *, int); 62int ki2c_write(struct ki2c_softc *, int, int, void *, int); 63 64/* I2C glue */ 65static int ki2c_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t, 66 void *, size_t, int); 67 68 69CFATTACH_DECL_NEW(ki2c, sizeof(struct ki2c_softc), ki2c_match, ki2c_attach, 70 NULL, NULL); 71 72int 73ki2c_match(device_t parent, cfdata_t match, void *aux) 74{ 75 struct confargs *ca = aux; 76 77 if (strcmp(ca->ca_name, "i2c") == 0) 78 return 1; 79 80 return 0; 81} 82 83void 84ki2c_attach(device_t parent, device_t self, void *aux) 85{ 86 struct ki2c_softc *sc = device_private(self); 87 struct confargs *ca = aux; 88 int node = ca->ca_node; 89 uint32_t addr, channel, reg; 90 int rate, child, /*namelen,*/ i2cbus[2] = {0, 0}; 91 struct i2cbus_attach_args iba; 92 prop_dictionary_t dict = device_properties(self); 93 prop_array_t cfg; 94 int devs, devc; 95 char compat[256], num[8], descr[32]; 96 prop_dictionary_t dev; 97 prop_data_t data; 98 char name[32]; 99 100 sc->sc_dev = self; 101 sc->sc_tag = ca->ca_tag; 102 ca->ca_reg[0] += ca->ca_baseaddr; 103 104 if (OF_getprop(node, "AAPL,i2c-rate", &rate, 4) != 4) { 105 aprint_error(": cannot get i2c-rate\n"); 106 return; 107 } 108 if (OF_getprop(node, "AAPL,address", &addr, 4) != 4) { 109 aprint_error(": unable to find i2c address\n"); 110 return; 111 } 112 if (bus_space_map(sc->sc_tag, addr, PAGE_SIZE, 0, &sc->sc_bh) != 0) { 113 aprint_error_dev(sc->sc_dev, "failed to map registers\n"); 114 return; 115 } 116 117 if (OF_getprop(node, "AAPL,address-step", &sc->sc_regstep, 4) != 4) { 118 aprint_error(": unable to find i2c address step\n"); 119 return; 120 } 121 122 printf("\n"); 123 124 ki2c_writereg(sc, STATUS, 0); 125 ki2c_writereg(sc, ISR, 0); 126 ki2c_writereg(sc, IER, 0); 127 128 ki2c_setmode(sc, I2C_STDSUBMODE); 129 ki2c_setspeed(sc, I2C_100kHz); /* XXX rate */ 130 131 ki2c_writereg(sc, IER,I2C_INT_DATA|I2C_INT_ADDR|I2C_INT_STOP); 132 133 cfg = prop_array_create(); 134 prop_dictionary_set(dict, "i2c-child-devices", cfg); 135 prop_object_release(cfg); 136 137 /* 138 * newer OF puts I2C devices under 'i2c-bus' instead of attaching them 139 * directly to the ki2c node so we just check if we have a child named 140 * 'i2c-bus' and if so we attach its children, not ours 141 * 142 * XXX 143 * should probably check for multiple i2c-bus children 144 */ 145 146 int found_busnode = 0; 147 channel = 0; 148 child = OF_child(node); 149 while (child != 0) { 150 OF_getprop(child, "name", name, sizeof(name)); 151 if (strcmp(name, "i2c-bus") == 0) { 152 OF_getprop(child, "reg", &channel, sizeof(channel)); 153 i2cbus[channel] = child; 154 DPRINTF("found channel %x\n", channel); 155 found_busnode = 1; 156 } 157 child = OF_peer(child); 158 } 159 if (found_busnode == 0) 160 i2cbus[0] = node; 161 162 for (channel = 0; channel < 2; channel++) { 163 devs = OF_child(i2cbus[channel]); 164 while (devs != 0) { 165 if (OF_getprop(devs, "name", name, 32) <= 0) 166 goto skip; 167 if (OF_getprop(devs, "compatible", compat, 256) <= 0) { 168 /* some i2c device nodes don't have 'compatible' */ 169 memset(compat, 0, 256); 170 strncpy(compat, name, 256); 171 } 172 if (OF_getprop(devs, "reg", &addr, 4) <= 0) 173 if (OF_getprop(devs, "i2c-address", &addr, 4) <= 0) 174 goto skip; 175 addr |= channel << 8; 176 addr = addr >> 1; 177 DPRINTF("-> %s@%x\n", name, addr); 178 dev = prop_dictionary_create(); 179 prop_dictionary_set_string(dev, "name", name); 180 data = prop_data_create_copy(compat, strlen(compat)+1); 181 prop_dictionary_set(dev, "compatible", data); 182 prop_object_release(data); 183 prop_dictionary_set_uint32(dev, "addr", addr); 184 prop_dictionary_set_uint64(dev, "cookie", devs); 185 /* look for location info for sensors */ 186 devc = OF_child(devs); 187 while (devc != 0) { 188 if (OF_getprop(devc, "reg", ®, 4) < 4) goto nope; 189 if (OF_getprop(devc, "location", descr, 32) <= 0) 190 goto nope; 191 DPRINTF("found '%s' at %02x\n", descr, reg); 192 snprintf(num, 7, "s%02x", reg); 193 prop_dictionary_set_string(dev, num, descr); 194 nope: 195 devc = OF_peer(devc); 196 } 197 prop_array_add(cfg, dev); 198 prop_object_release(dev); 199 skip: 200 devs = OF_peer(devs); 201 } 202 } 203 204 /* fill in the i2c tag */ 205 iic_tag_init(&sc->sc_i2c); 206 sc->sc_i2c.ic_cookie = sc; 207 sc->sc_i2c.ic_exec = ki2c_i2c_exec; 208 209 memset(&iba, 0, sizeof(iba)); 210 iba.iba_tag = &sc->sc_i2c; 211 config_found(sc->sc_dev, &iba, iicbus_print, CFARGS_NONE); 212 213} 214 215uint8_t 216ki2c_readreg(struct ki2c_softc *sc, int reg) 217{ 218 219 return bus_space_read_1(sc->sc_tag, sc->sc_bh, sc->sc_regstep * reg); 220} 221 222void 223ki2c_writereg(struct ki2c_softc *sc, int reg, uint8_t val) 224{ 225 226 bus_space_write_1(sc->sc_tag, sc->sc_bh, reg * sc->sc_regstep, val); 227 delay(10); 228} 229 230u_int 231ki2c_getmode(struct ki2c_softc *sc) 232{ 233 return ki2c_readreg(sc, MODE) & I2C_MODE; 234} 235 236void 237ki2c_setmode(struct ki2c_softc *sc, u_int mode) 238{ 239 ki2c_writereg(sc, MODE, mode); 240} 241 242u_int 243ki2c_getspeed(struct ki2c_softc *sc) 244{ 245 return ki2c_readreg(sc, MODE) & I2C_SPEED; 246} 247 248void 249ki2c_setspeed(struct ki2c_softc *sc, u_int speed) 250{ 251 u_int x; 252 253 KASSERT((speed & ~I2C_SPEED) == 0); 254 x = ki2c_readreg(sc, MODE); 255 x &= ~I2C_SPEED; 256 x |= speed; 257 ki2c_writereg(sc, MODE, x); 258} 259 260int 261ki2c_intr(struct ki2c_softc *sc) 262{ 263 u_int isr, x; 264 265 isr = ki2c_readreg(sc, ISR); 266 if (isr & I2C_INT_ADDR) { 267#if 0 268 if ((ki2c_readreg(sc, STATUS) & I2C_ST_LASTAAK) == 0) { 269 /* No slave responded. */ 270 sc->sc_flags |= I2C_ERROR; 271 goto out; 272 } 273#endif 274 275 if (sc->sc_flags & I2C_READING) { 276 if (sc->sc_resid > 1) { 277 x = ki2c_readreg(sc, CONTROL); 278 x |= I2C_CT_AAK; 279 ki2c_writereg(sc, CONTROL, x); 280 } 281 } else { 282 ki2c_writereg(sc, DATA, *sc->sc_data++); 283 sc->sc_resid--; 284 } 285 } 286 287 if (isr & I2C_INT_DATA) { 288 if (sc->sc_flags & I2C_READING) { 289 *sc->sc_data++ = ki2c_readreg(sc, DATA); 290 sc->sc_resid--; 291 292 if (sc->sc_resid == 0) { /* Completed */ 293 ki2c_writereg(sc, CONTROL, 0); 294 goto out; 295 } 296 } else { 297#if 0 298 if ((ki2c_readreg(sc, STATUS) & I2C_ST_LASTAAK) == 0) { 299 /* No slave responded. */ 300 sc->sc_flags |= I2C_ERROR; 301 goto out; 302 } 303#endif 304 305 if (sc->sc_resid == 0) { 306 x = ki2c_readreg(sc, CONTROL) | I2C_CT_STOP; 307 ki2c_writereg(sc, CONTROL, x); 308 } else { 309 ki2c_writereg(sc, DATA, *sc->sc_data++); 310 sc->sc_resid--; 311 } 312 } 313 } 314 315out: 316 if (isr & I2C_INT_STOP) { 317 ki2c_writereg(sc, CONTROL, 0); 318 sc->sc_flags &= ~I2C_BUSY; 319 } 320 321 ki2c_writereg(sc, ISR, isr); 322 323 return 1; 324} 325 326int 327ki2c_poll(struct ki2c_softc *sc, int timo) 328{ 329 while (sc->sc_flags & I2C_BUSY) { 330 if (ki2c_readreg(sc, ISR)) 331 ki2c_intr(sc); 332 timo -= 100; 333 if (timo < 0) { 334 DPRINTF("i2c_poll: timeout\n"); 335 return -1; 336 } 337 delay(100); 338 } 339 return 0; 340} 341 342int 343ki2c_start(struct ki2c_softc *sc, int addr, int subaddr, void *data, int len) 344{ 345 int rw = (sc->sc_flags & I2C_READING) ? 1 : 0; 346 int timo, x; 347 348 KASSERT((addr & 1) == 0); 349 350 sc->sc_data = data; 351 sc->sc_resid = len; 352 sc->sc_flags |= I2C_BUSY; 353 354 timo = 1000 + len * 200; 355 356 /* XXX TAS3001 sometimes takes 50ms to finish writing registers. */ 357 /* if (addr == 0x68) */ 358 timo += 100000; 359 360 ki2c_writereg(sc, ADDR, addr | rw); 361 ki2c_writereg(sc, SUBADDR, subaddr); 362 363 x = ki2c_readreg(sc, CONTROL) | I2C_CT_ADDR; 364 ki2c_writereg(sc, CONTROL, x); 365 366 if (ki2c_poll(sc, timo)) 367 return -1; 368 if (sc->sc_flags & I2C_ERROR) { 369 DPRINTF("I2C_ERROR\n"); 370 return -1; 371 } 372 return 0; 373} 374 375int 376ki2c_read(struct ki2c_softc *sc, int addr, int subaddr, void *data, int len) 377{ 378 sc->sc_flags = I2C_READING; 379 DPRINTF("ki2c_read: %02x %d\n", addr, len); 380 return ki2c_start(sc, addr, subaddr, data, len); 381} 382 383int 384ki2c_write(struct ki2c_softc *sc, int addr, int subaddr, void *data, int len) 385{ 386 sc->sc_flags = 0; 387 DPRINTF("ki2c_write: %02x %d\n",addr,len); 388 return ki2c_start(sc, addr, subaddr, data, len); 389} 390 391int 392ki2c_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *vcmd, 393 size_t cmdlen, void *vbuf, size_t buflen, int flags) 394{ 395 struct ki2c_softc *sc = cookie; 396 int i; 397 size_t w_len; 398 uint8_t *wp; 399 uint8_t wrbuf[KI2C_EXEC_MAX_CMDLEN + KI2C_EXEC_MAX_CMDLEN]; 400 uint8_t channel; 401 402 /* 403 * We don't have any idea if the ki2c controller can execute 404 * i2c quick_{read,write} operations, so if someone tries one, 405 * return an error. 406 */ 407 if (cmdlen == 0 && buflen == 0) 408 return -1; 409 410 /* 411 * Transaction could be much larger now. Bail if it exceeds our 412 * small combining buffer, we don't expect such devices. 413 */ 414 if (cmdlen + buflen > sizeof(wrbuf)) 415 return -1; 416 417 channel = (addr & 0xf80) ? 0x10 : 0x00; 418 addr &= 0x7f; 419 420 421 /* we handle the subaddress stuff ourselves */ 422 ki2c_setmode(sc, channel | I2C_STDMODE); 423 ki2c_setspeed(sc, I2C_50kHz); 424 425 /* Write-buffer defaults to vcmd */ 426 wp = (uint8_t *)(__UNCONST(vcmd)); 427 w_len = cmdlen; 428 429 /* 430 * Concatenate vcmd and vbuf for write operations 431 * 432 * Drivers written specifically for ki2c might already do this, 433 * but "generic" i2c drivers still provide separate arguments 434 * for the cmd and buf parts of iic_smbus_write_{byte,word}. 435 */ 436 if (I2C_OP_WRITE_P(op) && buflen != 0) { 437 if (cmdlen == 0) { 438 wp = (uint8_t *)vbuf; 439 w_len = buflen; 440 } else { 441 KASSERT((cmdlen + buflen) <= sizeof(wrbuf)); 442 wp = (uint8_t *)(__UNCONST(vcmd)); 443 w_len = 0; 444 for (i = 0; i < cmdlen; i++) 445 wrbuf[w_len++] = *wp++; 446 wp = (uint8_t *)vbuf; 447 for (i = 0; i < buflen; i++) 448 wrbuf[w_len++] = *wp++; 449 wp = wrbuf; 450 } 451 } 452 453 if (w_len > 0) 454 if (ki2c_write(sc, addr << 1, 0, wp, w_len) !=0 ) 455 return -1; 456 457 if (I2C_OP_READ_P(op)) { 458 if (ki2c_read(sc, addr << 1, 0, vbuf, buflen) !=0 ) 459 return -1; 460 } 461 return 0; 462} 463