1 /* 2 * Copyright (c) 2013 Patrick Wildt <patrick@blueri.se> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include "fdt.h" 18 19 #include <sys/param.h> 20 #include <sys/device.h> 21 #include <sys/kernel.h> 22 #include <sys/kthread.h> 23 #include <sys/malloc.h> 24 #include <sys/systm.h> 25 #include <machine/bus.h> 26 #if NFDT > 0 27 #include <machine/fdt.h> 28 #endif 29 30 #include <armv7/armv7/armv7var.h> 31 #include <armv7/exynos/exgpiovar.h> 32 #include <armv7/exynos/exiicvar.h> 33 #include <armv7/exynos/exclockvar.h> 34 35 /* registers */ 36 #define I2C_CON 0x00 /* control register */ 37 #define I2C_STAT 0x04 /* control/status register */ 38 #define I2C_ADD 0x08 /* address register */ 39 #define I2C_DS 0x0C /* transmit/receive data shift register */ 40 #define I2C_LC 0x10 /* multi-master line control register */ 41 42 /* bits and bytes */ 43 #define I2C_CON_TXCLKVAL_MASK (0xf << 0) /* tx clock = i2cclk / (i2ccon[3:0] + 1) */ 44 #define I2C_CON_INTPENDING (0x1 << 4) /* 0 = no interrupt pending/clear, 1 = pending */ 45 #define I2C_CON_TXRX_INT (0x1 << 5) /* enable/disable */ 46 #define I2C_CON_TXCLKSRC_16 (0x0 << 6) /* i2clk = fpclk/16 */ 47 #define I2C_CON_TXCLKSRC_512 (0x1 << 6) /* i2clk = fpclk/512 */ 48 #define I2C_CON_ACK (0x1 << 7) 49 #define I2C_STAT_LAST_RVCD_BIT (0x1 << 0) /* last received bit 0 => ack, 1 => no ack */ 50 #define I2C_STAT_ADDR_ZERO_FLAG (0x1 << 1) /* 0 => start/stop cond. detected, 1 => received slave addr 0xb */ 51 #define I2C_STAT_ADDR_SLAVE_ZERO_FLAG (0x1 << 2) /* 0 => start/stop cond. detected, 1 => received slave addr matches i2cadd */ 52 #define I2C_STAT_ARBITRATION (0x1 << 3) /* 0 => successul, 1 => failed */ 53 #define I2C_STAT_SERIAL_OUTPUT (0x1 << 4) /* 0 => disable tx/rx, 1 => enable tx/rx */ 54 #define I2C_STAT_BUSY_SIGNAL (0x1 << 5) /* 0 => not busy / stop signal generation, 1 => busy / start signal generation */ 55 #define I2C_STAT_MODE_SEL_SLAVE_RX (0x0 << 6) /* slave receive mode */ 56 #define I2C_STAT_MODE_SEL_SLAVE_TX (0x1 << 6) /* slave transmit mode */ 57 #define I2C_STAT_MODE_SEL_MASTER_RX (0x2 << 6) /* master receive mode */ 58 #define I2C_STAT_MODE_SEL_MASTER_TX (0x3 << 6) /* master transmit */ 59 #define I2C_ADD_SLAVE_ADDR(x) (((x) & 0x7f) << 1) 60 #define I2C_DS_DATA_SHIFT(x) (((x) & 0xff) << 0) 61 62 #define I2C_ACK 0 63 #define I2C_NACK 1 64 #define I2C_TIMEOUT 2 65 66 struct exiic_softc { 67 struct device sc_dev; 68 bus_space_tag_t sc_iot; 69 bus_space_handle_t sc_ioh; 70 bus_size_t sc_ios; 71 void *sc_ih; 72 int unit; 73 74 struct rwlock sc_buslock; 75 struct i2c_controller i2c_tag; 76 77 uint16_t frequency; 78 uint16_t intr_status; 79 }; 80 81 int exiic_match(struct device *parent, void *v, void *aux); 82 void exiic_attach(struct device *, struct device *, void *); 83 int exiic_detach(struct device *, int); 84 void exiic_bus_scan(struct device *, struct i2cbus_attach_args *, void *); 85 void exiic_setspeed(struct exiic_softc *, int); 86 int exiic_intr(void *); 87 int exiic_wait_intr(struct exiic_softc *, int, int); 88 int exiic_wait_state(struct exiic_softc *, uint32_t, uint32_t, uint32_t); 89 int exiic_start(struct exiic_softc *, int, int, void *, int); 90 91 void exiic_xfer_start(struct exiic_softc *); 92 int exiic_xfer_wait(struct exiic_softc *); 93 int exiic_i2c_acquire_bus(void *, int); 94 void exiic_i2c_release_bus(void *, int); 95 int exiic_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t, 96 void *, size_t, int); 97 98 #define HREAD4(sc, reg) \ 99 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) 100 #define HWRITE4(sc, reg, val) \ 101 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 102 #define HSET4(sc, reg, bits) \ 103 HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits)) 104 #define HCLR4(sc, reg, bits) \ 105 HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits)) 106 107 108 struct cfattach exiic_ca = { 109 sizeof(struct exiic_softc), NULL, exiic_attach, exiic_detach 110 }; 111 struct cfattach exiic_fdt_ca = { 112 sizeof(struct exiic_softc), exiic_match, exiic_attach, exiic_detach 113 }; 114 115 struct cfdriver exiic_cd = { 116 NULL, "exiic", DV_DULL 117 }; 118 119 int 120 exiic_match(struct device *parent, void *v, void *aux) 121 { 122 #if NFDT > 0 123 struct armv7_attach_args *aa = aux; 124 125 if (fdt_node_compatible("samsung,s3c2440-i2c", aa->aa_node)) 126 return 1; 127 #endif 128 129 return 0; 130 } 131 132 void 133 exiic_attach(struct device *parent, struct device *self, void *args) 134 { 135 struct exiic_softc *sc = (struct exiic_softc *)self; 136 struct armv7_attach_args *aa = args; 137 struct armv7mem mem; 138 139 sc->sc_iot = aa->aa_iot; 140 #if NFDT > 0 141 if (aa->aa_node) { 142 struct fdt_memory fdtmem; 143 static int unit = 0; 144 145 sc->unit = unit++; 146 if (fdt_get_memory_address(aa->aa_node, 0, &fdtmem)) 147 panic("%s: could not extract memory data from FDT", 148 __func__); 149 mem.addr = fdtmem.addr; 150 mem.size = fdtmem.size; 151 } else 152 #endif 153 { 154 mem.addr = aa->aa_dev->mem[0].addr; 155 mem.size = aa->aa_dev->mem[0].size; 156 sc->unit = aa->aa_dev->unit; 157 } 158 if (bus_space_map(sc->sc_iot, mem.addr, mem.size, 0, &sc->sc_ioh)) 159 panic("%s: bus_space_map failed!", __func__); 160 sc->sc_ios = mem.size; 161 162 #if 0 163 sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_BIO, 164 exiic_intr, sc, sc->sc_dev.dv_xname); 165 #endif 166 167 printf("\n"); 168 169 rw_init(&sc->sc_buslock, sc->sc_dev.dv_xname); 170 171 struct i2cbus_attach_args iba; 172 173 sc->i2c_tag.ic_cookie = sc; 174 sc->i2c_tag.ic_acquire_bus = exiic_i2c_acquire_bus; 175 sc->i2c_tag.ic_release_bus = exiic_i2c_release_bus; 176 sc->i2c_tag.ic_exec = exiic_i2c_exec; 177 178 bzero(&iba, sizeof iba); 179 iba.iba_name = "iic"; 180 iba.iba_tag = &sc->i2c_tag; 181 iba.iba_bus_scan = exiic_bus_scan; 182 iba.iba_bus_scan_arg = sc; 183 config_found(&sc->sc_dev, &iba, NULL); 184 } 185 186 void 187 exiic_bus_scan(struct device *self, struct i2cbus_attach_args *iba, void *arg) 188 { 189 struct exiic_softc *sc = (struct exiic_softc *)arg; 190 struct i2c_attach_args ia; 191 192 /* XXX: We currently only attach cros-ec on I2C4. We'll use FDT later. */ 193 if (sc->unit != 4) 194 return; 195 196 char *name = "crosec"; 197 int addr = 0x1e; 198 199 memset(&ia, 0, sizeof(ia)); 200 ia.ia_tag = iba->iba_tag; 201 ia.ia_addr = addr; 202 ia.ia_size = 1; 203 ia.ia_name = name; 204 config_found(self, &ia, iicbus_print); 205 206 name = "tps65090"; 207 addr = 0x48; 208 209 memset(&ia, 0, sizeof(ia)); 210 ia.ia_tag = iba->iba_tag; 211 ia.ia_addr = addr; 212 ia.ia_size = 1; 213 ia.ia_name = name; 214 config_found(self, &ia, iicbus_print); 215 } 216 217 void 218 exiic_setspeed(struct exiic_softc *sc, int speed) 219 { 220 if (!sc->frequency) { 221 uint32_t freq, div = 0, pres = 16; 222 freq = exclock_get_i2cclk(); 223 224 /* calculate prescaler and divisor values */ 225 if ((freq / pres / (16 + 1)) > speed) 226 /* set prescaler to 512 */ 227 pres = 512; 228 229 while ((freq / pres / (div + 1)) > speed) 230 div++; 231 232 /* set prescaler, divisor according to freq, also set ACKGEN, IRQ */ 233 sc->frequency = (div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0); 234 } 235 236 HWRITE4(sc, I2C_CON, sc->frequency); 237 } 238 239 #if 0 240 int 241 exiic_intr(void *arg) 242 { 243 struct exiic_softc *sc = arg; 244 u_int16_t status; 245 int rc = 0; 246 247 status = HREAD4(sc, I2C_CON); 248 249 if (ISSET(status, I2C_CON_INTPENDING)) { 250 /* we do not acknowledge the interrupt here */ 251 rc = 1; 252 253 sc->intr_status |= status; 254 wakeup(&sc->intr_status); 255 } 256 257 return (rc); 258 } 259 260 int 261 exiic_wait_intr(struct exiic_softc *sc, int mask, int timo) 262 { 263 int status; 264 int s; 265 266 s = splbio(); 267 268 status = sc->intr_status & mask; 269 while (status == 0) { 270 if (tsleep(&sc->intr_status, PWAIT, "hcintr", timo) 271 == EWOULDBLOCK) { 272 break; 273 } 274 status = sc->intr_status & mask; 275 } 276 status = sc->intr_status & mask; 277 sc->intr_status &= ~status; 278 279 splx(s); 280 return status; 281 } 282 #endif 283 284 int 285 exiic_wait_state(struct exiic_softc *sc, uint32_t reg, uint32_t mask, uint32_t value) 286 { 287 uint32_t state; 288 int timeout; 289 state = HREAD4(sc, reg); 290 for (timeout = 1000; timeout > 0; timeout--) { 291 if (((state = HREAD4(sc, reg)) & mask) == value) 292 return 0; 293 delay(1000); 294 } 295 return ETIMEDOUT; 296 } 297 298 int 299 exiic_i2c_acquire_bus(void *cookie, int flags) 300 { 301 struct exiic_softc *sc = cookie; 302 int ret = rw_enter(&sc->sc_buslock, RW_WRITE); 303 304 if (!ret) { 305 /* set speed to 100 Kbps */ 306 exiic_setspeed(sc, 100); 307 308 /* STOP */ 309 HWRITE4(sc, I2C_STAT, 0); 310 HWRITE4(sc, I2C_ADD, 0); 311 HWRITE4(sc, I2C_STAT, I2C_STAT_MODE_SEL_MASTER_TX 312 | I2C_STAT_SERIAL_OUTPUT); 313 } 314 315 return ret; 316 } 317 318 void 319 exiic_i2c_release_bus(void *cookie, int flags) 320 { 321 struct exiic_softc *sc = cookie; 322 323 (void) rw_exit(&sc->sc_buslock); 324 } 325 326 int 327 exiic_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t _addr, 328 const void *cmdbuf, size_t cmdlen, void *databuf, size_t datalen, int flags) 329 { 330 struct exiic_softc *sc = cookie; 331 uint32_t ret = 0; 332 u_int8_t addr = 0; 333 int i = 0; 334 335 addr = (_addr & 0x7f) << 1; 336 337 /* clock gating */ 338 //exccm_enable_i2c(sc->unit); 339 340 if (exiic_wait_state(sc, I2C_STAT, I2C_STAT_BUSY_SIGNAL, 0)) { 341 printf("%s: busy\n", __func__); 342 return (EIO); 343 } 344 345 /* acknowledge generation */ 346 HSET4(sc, I2C_CON, I2C_CON_ACK); 347 348 /* Send the slave-address */ 349 HWRITE4(sc, I2C_DS, addr); 350 if (!I2C_OP_READ_P(op) || (cmdbuf && cmdlen)) 351 HWRITE4(sc, I2C_STAT, I2C_STAT_MODE_SEL_MASTER_TX 352 | I2C_STAT_SERIAL_OUTPUT 353 | I2C_STAT_BUSY_SIGNAL); 354 else 355 HWRITE4(sc, I2C_STAT, I2C_STAT_MODE_SEL_MASTER_RX 356 | I2C_STAT_SERIAL_OUTPUT 357 | I2C_STAT_BUSY_SIGNAL); 358 359 ret = exiic_xfer_wait(sc); 360 if (ret != I2C_ACK) 361 goto fail; 362 363 /* transmit commands */ 364 if (cmdbuf && cmdlen) { 365 for (i = 0; i < cmdlen; i++) { 366 HWRITE4(sc, I2C_DS, ((uint8_t *)cmdbuf)[i]); 367 exiic_xfer_start(sc); 368 ret = exiic_xfer_wait(sc); 369 if (ret != I2C_ACK) 370 goto fail; 371 } 372 } 373 374 if (I2C_OP_READ_P(op)) { 375 if (cmdbuf && cmdlen) { 376 /* write slave chip address again for actual read */ 377 HWRITE4(sc, I2C_DS, addr); 378 379 /* restart */ 380 HWRITE4(sc, I2C_STAT, I2C_STAT_MODE_SEL_MASTER_RX 381 | I2C_STAT_SERIAL_OUTPUT 382 | I2C_STAT_BUSY_SIGNAL); 383 exiic_xfer_start(sc); 384 ret = exiic_xfer_wait(sc); 385 if (ret != I2C_ACK) 386 goto fail; 387 } 388 389 for (i = 0; i < datalen && ret == I2C_ACK; i++) { 390 /* disable ACK for final read */ 391 if (i == datalen - 1) 392 HCLR4(sc, I2C_CON, I2C_CON_ACK); 393 exiic_xfer_start(sc); 394 ret = exiic_xfer_wait(sc); 395 ((uint8_t *)databuf)[i] = HREAD4(sc, I2C_DS); 396 } 397 if (ret == I2C_NACK) 398 ret = I2C_ACK; /* Normal terminated read. */ 399 } else { 400 for (i = 0; i < datalen && ret == I2C_ACK; i++) { 401 HWRITE4(sc, I2C_DS, ((uint8_t *)databuf)[i]); 402 exiic_xfer_start(sc); 403 ret = exiic_xfer_wait(sc); 404 } 405 } 406 407 fail: 408 /* send STOP */ 409 if (op & I2C_OP_READ_WITH_STOP) { 410 HWRITE4(sc, I2C_STAT, I2C_STAT_MODE_SEL_MASTER_RX 411 | I2C_STAT_SERIAL_OUTPUT); 412 exiic_xfer_start(sc); 413 } 414 415 return ret; 416 } 417 418 void 419 exiic_xfer_start(struct exiic_softc *sc) 420 { 421 HCLR4(sc, I2C_CON, I2C_CON_INTPENDING); 422 } 423 424 int 425 exiic_xfer_wait(struct exiic_softc *sc) 426 { 427 if (!exiic_wait_state(sc, I2C_CON, I2C_CON_INTPENDING, 428 I2C_CON_INTPENDING)) 429 return (HREAD4(sc, I2C_STAT) & I2C_STAT_LAST_RVCD_BIT) ? 430 I2C_NACK : I2C_ACK; 431 else 432 return I2C_TIMEOUT; 433 } 434 435 int 436 exiic_detach(struct device *self, int flags) 437 { 438 struct exiic_softc *sc = (struct exiic_softc *)self; 439 440 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); 441 return 0; 442 } 443