1 /* 2 * TI OMAP on-chip I2C controller. Only "new I2C" mode supported. 3 * 4 * Copyright (C) 2007 Andrzej Zaborowski <balrog@zabor.org> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 #include "qemu/osdep.h" 20 #include "hw/hw.h" 21 #include "hw/i2c/i2c.h" 22 #include "hw/arm/omap.h" 23 #include "hw/sysbus.h" 24 #include "qemu/error-report.h" 25 #include "qapi/error.h" 26 27 #define TYPE_OMAP_I2C "omap_i2c" 28 #define OMAP_I2C(obj) OBJECT_CHECK(OMAPI2CState, (obj), TYPE_OMAP_I2C) 29 30 typedef struct OMAPI2CState { 31 SysBusDevice parent_obj; 32 33 MemoryRegion iomem; 34 qemu_irq irq; 35 qemu_irq drq[2]; 36 I2CBus *bus; 37 38 uint8_t revision; 39 void *iclk; 40 void *fclk; 41 42 uint8_t mask; 43 uint16_t stat; 44 uint16_t dma; 45 uint16_t count; 46 int count_cur; 47 uint32_t fifo; 48 int rxlen; 49 int txlen; 50 uint16_t control; 51 uint16_t addr[2]; 52 uint8_t divider; 53 uint8_t times[2]; 54 uint16_t test; 55 } OMAPI2CState; 56 57 #define OMAP2_INTR_REV 0x34 58 #define OMAP2_GC_REV 0x34 59 60 static void omap_i2c_interrupts_update(OMAPI2CState *s) 61 { 62 qemu_set_irq(s->irq, s->stat & s->mask); 63 if ((s->dma >> 15) & 1) /* RDMA_EN */ 64 qemu_set_irq(s->drq[0], (s->stat >> 3) & 1); /* RRDY */ 65 if ((s->dma >> 7) & 1) /* XDMA_EN */ 66 qemu_set_irq(s->drq[1], (s->stat >> 4) & 1); /* XRDY */ 67 } 68 69 static void omap_i2c_fifo_run(OMAPI2CState *s) 70 { 71 int ack = 1; 72 73 if (!i2c_bus_busy(s->bus)) 74 return; 75 76 if ((s->control >> 2) & 1) { /* RM */ 77 if ((s->control >> 1) & 1) { /* STP */ 78 i2c_end_transfer(s->bus); 79 s->control &= ~(1 << 1); /* STP */ 80 s->count_cur = s->count; 81 s->txlen = 0; 82 } else if ((s->control >> 9) & 1) { /* TRX */ 83 while (ack && s->txlen) 84 ack = (i2c_send(s->bus, 85 (s->fifo >> ((-- s->txlen) << 3)) & 86 0xff) >= 0); 87 s->stat |= 1 << 4; /* XRDY */ 88 } else { 89 while (s->rxlen < 4) 90 s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3); 91 s->stat |= 1 << 3; /* RRDY */ 92 } 93 } else { 94 if ((s->control >> 9) & 1) { /* TRX */ 95 while (ack && s->count_cur && s->txlen) { 96 ack = (i2c_send(s->bus, 97 (s->fifo >> ((-- s->txlen) << 3)) & 98 0xff) >= 0); 99 s->count_cur --; 100 } 101 if (ack && s->count_cur) 102 s->stat |= 1 << 4; /* XRDY */ 103 else 104 s->stat &= ~(1 << 4); /* XRDY */ 105 if (!s->count_cur) { 106 s->stat |= 1 << 2; /* ARDY */ 107 s->control &= ~(1 << 10); /* MST */ 108 } 109 } else { 110 while (s->count_cur && s->rxlen < 4) { 111 s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3); 112 s->count_cur --; 113 } 114 if (s->rxlen) 115 s->stat |= 1 << 3; /* RRDY */ 116 else 117 s->stat &= ~(1 << 3); /* RRDY */ 118 } 119 if (!s->count_cur) { 120 if ((s->control >> 1) & 1) { /* STP */ 121 i2c_end_transfer(s->bus); 122 s->control &= ~(1 << 1); /* STP */ 123 s->count_cur = s->count; 124 s->txlen = 0; 125 } else { 126 s->stat |= 1 << 2; /* ARDY */ 127 s->control &= ~(1 << 10); /* MST */ 128 } 129 } 130 } 131 132 s->stat |= (!ack) << 1; /* NACK */ 133 if (!ack) 134 s->control &= ~(1 << 1); /* STP */ 135 } 136 137 static void omap_i2c_reset(DeviceState *dev) 138 { 139 OMAPI2CState *s = OMAP_I2C(dev); 140 141 s->mask = 0; 142 s->stat = 0; 143 s->dma = 0; 144 s->count = 0; 145 s->count_cur = 0; 146 s->fifo = 0; 147 s->rxlen = 0; 148 s->txlen = 0; 149 s->control = 0; 150 s->addr[0] = 0; 151 s->addr[1] = 0; 152 s->divider = 0; 153 s->times[0] = 0; 154 s->times[1] = 0; 155 s->test = 0; 156 } 157 158 static uint32_t omap_i2c_read(void *opaque, hwaddr addr) 159 { 160 OMAPI2CState *s = opaque; 161 int offset = addr & OMAP_MPUI_REG_MASK; 162 uint16_t ret; 163 164 switch (offset) { 165 case 0x00: /* I2C_REV */ 166 return s->revision; /* REV */ 167 168 case 0x04: /* I2C_IE */ 169 return s->mask; 170 171 case 0x08: /* I2C_STAT */ 172 return s->stat | (i2c_bus_busy(s->bus) << 12); 173 174 case 0x0c: /* I2C_IV */ 175 if (s->revision >= OMAP2_INTR_REV) 176 break; 177 ret = ctz32(s->stat & s->mask); 178 if (ret != 32) { 179 s->stat ^= 1 << ret; 180 ret++; 181 } else { 182 ret = 0; 183 } 184 omap_i2c_interrupts_update(s); 185 return ret; 186 187 case 0x10: /* I2C_SYSS */ 188 return (s->control >> 15) & 1; /* I2C_EN */ 189 190 case 0x14: /* I2C_BUF */ 191 return s->dma; 192 193 case 0x18: /* I2C_CNT */ 194 return s->count_cur; /* DCOUNT */ 195 196 case 0x1c: /* I2C_DATA */ 197 ret = 0; 198 if (s->control & (1 << 14)) { /* BE */ 199 ret |= ((s->fifo >> 0) & 0xff) << 8; 200 ret |= ((s->fifo >> 8) & 0xff) << 0; 201 } else { 202 ret |= ((s->fifo >> 8) & 0xff) << 8; 203 ret |= ((s->fifo >> 0) & 0xff) << 0; 204 } 205 if (s->rxlen == 1) { 206 s->stat |= 1 << 15; /* SBD */ 207 s->rxlen = 0; 208 } else if (s->rxlen > 1) { 209 if (s->rxlen > 2) 210 s->fifo >>= 16; 211 s->rxlen -= 2; 212 } else { 213 /* XXX: remote access (qualifier) error - what's that? */ 214 } 215 if (!s->rxlen) { 216 s->stat &= ~(1 << 3); /* RRDY */ 217 if (((s->control >> 10) & 1) && /* MST */ 218 ((~s->control >> 9) & 1)) { /* TRX */ 219 s->stat |= 1 << 2; /* ARDY */ 220 s->control &= ~(1 << 10); /* MST */ 221 } 222 } 223 s->stat &= ~(1 << 11); /* ROVR */ 224 omap_i2c_fifo_run(s); 225 omap_i2c_interrupts_update(s); 226 return ret; 227 228 case 0x20: /* I2C_SYSC */ 229 return 0; 230 231 case 0x24: /* I2C_CON */ 232 return s->control; 233 234 case 0x28: /* I2C_OA */ 235 return s->addr[0]; 236 237 case 0x2c: /* I2C_SA */ 238 return s->addr[1]; 239 240 case 0x30: /* I2C_PSC */ 241 return s->divider; 242 243 case 0x34: /* I2C_SCLL */ 244 return s->times[0]; 245 246 case 0x38: /* I2C_SCLH */ 247 return s->times[1]; 248 249 case 0x3c: /* I2C_SYSTEST */ 250 if (s->test & (1 << 15)) { /* ST_EN */ 251 s->test ^= 0xa; 252 return s->test; 253 } else 254 return s->test & ~0x300f; 255 } 256 257 OMAP_BAD_REG(addr); 258 return 0; 259 } 260 261 static void omap_i2c_write(void *opaque, hwaddr addr, 262 uint32_t value) 263 { 264 OMAPI2CState *s = opaque; 265 int offset = addr & OMAP_MPUI_REG_MASK; 266 int nack; 267 268 switch (offset) { 269 case 0x00: /* I2C_REV */ 270 case 0x0c: /* I2C_IV */ 271 case 0x10: /* I2C_SYSS */ 272 OMAP_RO_REG(addr); 273 return; 274 275 case 0x04: /* I2C_IE */ 276 s->mask = value & (s->revision < OMAP2_GC_REV ? 0x1f : 0x3f); 277 break; 278 279 case 0x08: /* I2C_STAT */ 280 if (s->revision < OMAP2_INTR_REV) { 281 OMAP_RO_REG(addr); 282 return; 283 } 284 285 /* RRDY and XRDY are reset by hardware. (in all versions???) */ 286 s->stat &= ~(value & 0x27); 287 omap_i2c_interrupts_update(s); 288 break; 289 290 case 0x14: /* I2C_BUF */ 291 s->dma = value & 0x8080; 292 if (value & (1 << 15)) /* RDMA_EN */ 293 s->mask &= ~(1 << 3); /* RRDY_IE */ 294 if (value & (1 << 7)) /* XDMA_EN */ 295 s->mask &= ~(1 << 4); /* XRDY_IE */ 296 break; 297 298 case 0x18: /* I2C_CNT */ 299 s->count = value; /* DCOUNT */ 300 break; 301 302 case 0x1c: /* I2C_DATA */ 303 if (s->txlen > 2) { 304 /* XXX: remote access (qualifier) error - what's that? */ 305 break; 306 } 307 s->fifo <<= 16; 308 s->txlen += 2; 309 if (s->control & (1 << 14)) { /* BE */ 310 s->fifo |= ((value >> 8) & 0xff) << 8; 311 s->fifo |= ((value >> 0) & 0xff) << 0; 312 } else { 313 s->fifo |= ((value >> 0) & 0xff) << 8; 314 s->fifo |= ((value >> 8) & 0xff) << 0; 315 } 316 s->stat &= ~(1 << 10); /* XUDF */ 317 if (s->txlen > 2) 318 s->stat &= ~(1 << 4); /* XRDY */ 319 omap_i2c_fifo_run(s); 320 omap_i2c_interrupts_update(s); 321 break; 322 323 case 0x20: /* I2C_SYSC */ 324 if (s->revision < OMAP2_INTR_REV) { 325 OMAP_BAD_REG(addr); 326 return; 327 } 328 329 if (value & 2) { 330 omap_i2c_reset(DEVICE(s)); 331 } 332 break; 333 334 case 0x24: /* I2C_CON */ 335 s->control = value & 0xcf87; 336 if (~value & (1 << 15)) { /* I2C_EN */ 337 if (s->revision < OMAP2_INTR_REV) { 338 omap_i2c_reset(DEVICE(s)); 339 } 340 break; 341 } 342 if ((value & (1 << 15)) && !(value & (1 << 10))) { /* MST */ 343 fprintf(stderr, "%s: I^2C slave mode not supported\n", 344 __FUNCTION__); 345 break; 346 } 347 if ((value & (1 << 15)) && value & (1 << 8)) { /* XA */ 348 fprintf(stderr, "%s: 10-bit addressing mode not supported\n", 349 __FUNCTION__); 350 break; 351 } 352 if ((value & (1 << 15)) && value & (1 << 0)) { /* STT */ 353 nack = !!i2c_start_transfer(s->bus, s->addr[1], /* SA */ 354 (~value >> 9) & 1); /* TRX */ 355 s->stat |= nack << 1; /* NACK */ 356 s->control &= ~(1 << 0); /* STT */ 357 s->fifo = 0; 358 if (nack) 359 s->control &= ~(1 << 1); /* STP */ 360 else { 361 s->count_cur = s->count; 362 omap_i2c_fifo_run(s); 363 } 364 omap_i2c_interrupts_update(s); 365 } 366 break; 367 368 case 0x28: /* I2C_OA */ 369 s->addr[0] = value & 0x3ff; 370 break; 371 372 case 0x2c: /* I2C_SA */ 373 s->addr[1] = value & 0x3ff; 374 break; 375 376 case 0x30: /* I2C_PSC */ 377 s->divider = value; 378 break; 379 380 case 0x34: /* I2C_SCLL */ 381 s->times[0] = value; 382 break; 383 384 case 0x38: /* I2C_SCLH */ 385 s->times[1] = value; 386 break; 387 388 case 0x3c: /* I2C_SYSTEST */ 389 s->test = value & 0xf80f; 390 if (value & (1 << 11)) /* SBB */ 391 if (s->revision >= OMAP2_INTR_REV) { 392 s->stat |= 0x3f; 393 omap_i2c_interrupts_update(s); 394 } 395 if (value & (1 << 15)) /* ST_EN */ 396 fprintf(stderr, "%s: System Test not supported\n", __FUNCTION__); 397 break; 398 399 default: 400 OMAP_BAD_REG(addr); 401 return; 402 } 403 } 404 405 static void omap_i2c_writeb(void *opaque, hwaddr addr, 406 uint32_t value) 407 { 408 OMAPI2CState *s = opaque; 409 int offset = addr & OMAP_MPUI_REG_MASK; 410 411 switch (offset) { 412 case 0x1c: /* I2C_DATA */ 413 if (s->txlen > 2) { 414 /* XXX: remote access (qualifier) error - what's that? */ 415 break; 416 } 417 s->fifo <<= 8; 418 s->txlen += 1; 419 s->fifo |= value & 0xff; 420 s->stat &= ~(1 << 10); /* XUDF */ 421 if (s->txlen > 2) 422 s->stat &= ~(1 << 4); /* XRDY */ 423 omap_i2c_fifo_run(s); 424 omap_i2c_interrupts_update(s); 425 break; 426 427 default: 428 OMAP_BAD_REG(addr); 429 return; 430 } 431 } 432 433 static const MemoryRegionOps omap_i2c_ops = { 434 .old_mmio = { 435 .read = { 436 omap_badwidth_read16, 437 omap_i2c_read, 438 omap_badwidth_read16, 439 }, 440 .write = { 441 omap_i2c_writeb, /* Only the last fifo write can be 8 bit. */ 442 omap_i2c_write, 443 omap_badwidth_write16, 444 }, 445 }, 446 .endianness = DEVICE_NATIVE_ENDIAN, 447 }; 448 449 static void omap_i2c_init(Object *obj) 450 { 451 DeviceState *dev = DEVICE(obj); 452 OMAPI2CState *s = OMAP_I2C(obj); 453 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 454 455 sysbus_init_irq(sbd, &s->irq); 456 sysbus_init_irq(sbd, &s->drq[0]); 457 sysbus_init_irq(sbd, &s->drq[1]); 458 sysbus_init_mmio(sbd, &s->iomem); 459 s->bus = i2c_init_bus(dev, NULL); 460 } 461 462 static void omap_i2c_realize(DeviceState *dev, Error **errp) 463 { 464 OMAPI2CState *s = OMAP_I2C(dev); 465 466 memory_region_init_io(&s->iomem, OBJECT(dev), &omap_i2c_ops, s, "omap.i2c", 467 (s->revision < OMAP2_INTR_REV) ? 0x800 : 0x1000); 468 469 if (!s->fclk) { 470 error_setg(errp, "omap_i2c: fclk not connected"); 471 return; 472 } 473 if (s->revision >= OMAP2_INTR_REV && !s->iclk) { 474 /* Note that OMAP1 doesn't have a separate interface clock */ 475 error_setg(errp, "omap_i2c: iclk not connected"); 476 return; 477 } 478 } 479 480 static Property omap_i2c_properties[] = { 481 DEFINE_PROP_UINT8("revision", OMAPI2CState, revision, 0), 482 DEFINE_PROP_PTR("iclk", OMAPI2CState, iclk), 483 DEFINE_PROP_PTR("fclk", OMAPI2CState, fclk), 484 DEFINE_PROP_END_OF_LIST(), 485 }; 486 487 static void omap_i2c_class_init(ObjectClass *klass, void *data) 488 { 489 DeviceClass *dc = DEVICE_CLASS(klass); 490 491 dc->props = omap_i2c_properties; 492 dc->reset = omap_i2c_reset; 493 /* Reason: pointer properties "iclk", "fclk" */ 494 dc->cannot_instantiate_with_device_add_yet = true; 495 dc->realize = omap_i2c_realize; 496 } 497 498 static const TypeInfo omap_i2c_info = { 499 .name = TYPE_OMAP_I2C, 500 .parent = TYPE_SYS_BUS_DEVICE, 501 .instance_size = sizeof(OMAPI2CState), 502 .instance_init = omap_i2c_init, 503 .class_init = omap_i2c_class_init, 504 }; 505 506 static void omap_i2c_register_types(void) 507 { 508 type_register_static(&omap_i2c_info); 509 } 510 511 I2CBus *omap_i2c_bus(DeviceState *omap_i2c) 512 { 513 OMAPI2CState *s = OMAP_I2C(omap_i2c); 514 return s->bus; 515 } 516 517 type_init(omap_i2c_register_types) 518